Compare commits

...

186 Commits

Author SHA1 Message Date
Wayne Stambaugh 3d87537dd2 Tag release version 6.0.5. 2022-05-02 15:37:58 -04:00
Marek Roszko 862d975c2c Update vcpkg manifest for debuggable wxwidgets 3.1.5 2022-04-30 23:10:15 -04:00
Mark Roszko 45d58fbefc Remove errant phoenix message when disabled 2022-04-30 23:10:10 -04:00
Mark Roszko 7b7e4e1ae5 Move forwards kicad-vcpkg registry to get our ngspice 2022-04-30 03:40:40 +00:00
Marek Roszko 3f04b80ff4 Remove the vcpkg specific hack to FindwxWidgets.cmake which is no longer needed/broken with manifests 2022-04-28 23:27:09 -04:00
Mark Roszko 5830cdd1c0 Disable windows ci for now 2022-04-29 01:24:09 +00:00
Marek Roszko 2416b28cda Add vcpkg manifest 2022-04-28 21:20:30 -04:00
Seth Hillbrand 729cf7a39d Use instance data to store values
Previous use of instance was as an "override" of the default value.
This has changed to be used as the primary storage location for all
values.  This means that we cannot clear the instance data when setting
a new value for all instances, instead we have to change the instance
data and the default value is superfluous

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

(cherry picked from commit 1a70465927)
2022-04-25 13:03:41 -07:00
Seth Hillbrand 4d56690a7e Update Translations 2022-04-19 14:55:57 -07:00
Henrik Kauhanen e30128f6f5 Translated using Weblate (Swedish)
Currently translated at 99.7% (7190 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-04-19 23:54:45 +02:00
ZbeeGin c4a42f28c8 Translated using Weblate (Polish)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-04-19 23:54:45 +02:00
co8 j bdbbba54f9 Translated using Weblate (Japanese)
Currently translated at 99.8% (7201 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-04-19 23:54:45 +02:00
Toni Laiho 80c2fb39b1 Translated using Weblate (Finnish)
Currently translated at 99.9% (7205 of 7211 strings)

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

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-04-19 23:54:44 +02:00
Jan Straka 6c1d615f66 Translated using Weblate (Czech)
Currently translated at 91.8% (6622 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-04-19 23:54:44 +02:00
Jan Straka c0ca2f1830 Translated using Weblate (Czech)
Currently translated at 91.7% (6613 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-04-19 23:54:44 +02:00
Seth Hillbrand cf5f36aac5 Fix broken comparison in pin_numbers
Pin names like "+V" were incorrectly parsed as doubles leading to broken
comparisons.  These caused heap overflows when sorting pin tables

This corrects the comparison so that numeric sorts are only performed
when there is an actual number in the symbol segment.  Also adds unit
tests for common error cases

(cherry picked from commit aac6f576c2)
2022-04-19 14:49:52 -07:00
Simon Richter cc51807241 Fix minimum size calculation for new hierarchical sheets
These constants are given in mil, but are used in a context of internal
units.
2022-04-18 02:16:17 +02:00
Marco Ciampa e1865c1178 Updated Italian translation 2022-04-17 10:49:41 +02:00
Henrik Kauhanen b81ba520f8 Translated using Weblate (Swedish)
Currently translated at 99.7% (7190 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-04-16 00:13:45 +02:00
Toni Laiho edbb9c5194 Translated using Weblate (Finnish)
Currently translated at 99.9% (7205 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-04-16 00:13:45 +02:00
Eric cda6aed408 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-04-16 00:13:45 +02:00
Henrik Kauhanen 74172612fa Translated using Weblate (Swedish)
Currently translated at 99.6% (7188 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-04-16 00:13:45 +02:00
Wellington Terumi Uemura 7209239a62 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-04-16 00:13:45 +02:00
Bas Wijnen 16edde8611 Translated using Weblate (Dutch)
Currently translated at 98.4% (7098 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/nl/
2022-04-16 00:13:45 +02:00
Toni Laiho 33f8bcb7c7 Translated using Weblate (Finnish)
Currently translated at 99.8% (7203 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-04-16 00:13:45 +02:00
Ulices fb6505d8cb Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-04-16 00:13:44 +02:00
Arnau Llovet Vidal 39935311fc Translated using Weblate (Catalan)
Currently translated at 65.8% (4749 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-04-16 00:13:44 +02:00
Seth Hillbrand 851f893e8e Fix crash due to cleared view data
When changing fields, we need to update the view before allowing canvas
updates
2022-04-15 14:56:18 -07:00
Seth Hillbrand bfa1661edf Sync via/pad flashing for null boards
Pads return true by default and so should vias
2022-04-15 11:39:18 -07:00
Jeff Young 110663d214 Fix crash bug when selecting marker. 2022-04-15 13:40:19 +01:00
Jeff Young 847fa7f2c4 Add PCB_ARCs to type enum.
Fixes https://gitlab.com/kicad/code/kicad/issues/11384

(cherry picked from commit d01c2a6614)
2022-04-14 18:37:25 +01:00
jean-pierre charras ef798f446f STEP export: handle polygons with arcs (and convert arcs to segments).
From Master branch
Fixes #11389
https://gitlab.com/kicad/code/kicad/issues/11389
2022-04-14 16:31:56 +02:00
jean-pierre charras 2de1bd7a4a Ensure "Open Recent" and "Clear files" menu titles are updated after language change.
From Master branch.
2022-04-14 15:06:17 +02:00
Roberto Fernandez Bautista 250942264b CADSTAR Sch: Clear symbol of all elements before overwriting with new one
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11378

(cherry picked from commit 85f6ff48e7)
2022-04-12 21:42:03 +01:00
Jeff Young 6818eff90e Improvements to Eagle dimension importing.
1) Import leaders
2) Drop radius and angle dimensions
3) Import dimension text sizes
4) Correctly interpret which side dimension offset is on
5) Correclty handle offsets for non-cardinal dimensions

Fixes https://gitlab.com/kicad/code/kicad/issues/10763
2022-04-12 13:24:34 +01:00
Jeff Young b2eb1f829e Dual-purpose IsMovableFromAnchorPoint to keep from moving symbols off-grid.
Fixes https://gitlab.com/kicad/code/kicad/issues/11360

(cherry picked from commit 8358685920)
2022-04-12 13:24:34 +01:00
Jeff Young a60e7e27b6 A better blob vs web detector.
Since we're in a deflated state, a long web *could* still have a very
small area.  So check max extents instead.

(cherry picked from commit 1dae5eb7c4)
2022-04-12 13:24:34 +01:00
Jeff Young 601995c759 Apply the min-width-by-min-width test to islands after pruning.
We're looking for minimum *web* width.  A blob does not a web make.

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

(cherry picked from commit 1a2e0d8226)
2022-04-12 13:24:14 +01:00
Jeff Young 63ce2307c8 Adjust LIB_SYMBOL compare for use with ERC.
Fixes https://gitlab.com/kicad/code/kicad/issues/10783

(cherry picked from commit 117bd4fc22)
2022-04-12 13:24:14 +01:00
Jeff Young 03bc9551c7 Don't save schematic symbol back to lib manager.
Also, since it doesn't get saved, changing symbols will lose any edits.
Make sure to ask the user first.

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

(cherry picked from commit 16acba34d3)
2022-04-12 13:24:14 +01:00
Jeff Young c8cd214cb0 Make sure to add any now-necessary junctions after a rotate.
Fixes https://gitlab.com/kicad/code/kicad/issues/11242

(cherry picked from commit 74a578047c)
2022-04-12 13:24:14 +01:00
Marek Roszko fe11bc8330 Change the behavior of ACTION_MENU::Add to require clones if required outside the function 2022-04-11 20:39:08 -04:00
Seth Hillbrand d0796399a2 DP tolerance needs to be 1IU on each axis
ApproximatelyParallel will only check for parallel within 1 IU, so a 1x1
SEG will always be parallel and the projection is invalid
2022-04-11 16:55:54 -07:00
Seth Hillbrand c2d72180f8 Revert "Change the behavior of ACTION_MENU::Add to require clones if required outside the function"
This reverts commit 651f50a26d.
2022-04-11 11:03:19 -07:00
Seth Hillbrand 57729414e3 Update Translations 2022-04-11 09:40:06 -07:00
Henrik Kauhanen b664fb7a7d Translated using Weblate (Swedish)
Currently translated at 99.7% (7191 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-04-11 18:38:45 +02:00
Toni Laiho fe1a8bea8c Translated using Weblate (Finnish)
Currently translated at 99.8% (7202 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-04-11 18:38:45 +02:00
Tian Yunhao 3606ad725c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-04-11 18:38:45 +02:00
Eric e8e24b372f Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-04-11 18:38:45 +02:00
Henrik Kauhanen 3bfa5807c8 Translated using Weblate (Swedish)
Currently translated at 99.7% (7191 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-04-11 18:38:44 +02:00
Toni Laiho b797735c24 Translated using Weblate (Finnish)
Currently translated at 99.9% (7203 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-04-11 18:38:44 +02:00
Ulices d0af5fb5fc Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-04-11 18:38:44 +02:00
Mark Hämmerling 5ca91c404a Translated using Weblate (German)
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-04-11 18:38:44 +02:00
Jan Straka 6ba7967adc Translated using Weblate (Czech)
Currently translated at 91.6% (6608 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-04-11 18:38:44 +02:00
Arnau Llovet Vidal 9dfc492cb9 Translated using Weblate (Catalan)
Currently translated at 65.7% (4741 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-04-11 18:38:44 +02:00
Marco Ciampa 0876fed91b Small fix in Italian translation 2022-04-11 10:06:56 +02:00
Marek Roszko 651f50a26d Change the behavior of ACTION_MENU::Add to require clones if required outside the function
Fix https://gitlab.com/kicad/code/kicad/-/issues/10994
2022-04-10 22:40:58 -04:00
Marek Roszko 99456d4351 Don't pointlessly construct a wxBitmap
(cherry picked from commit fd83e675a2)
2022-04-10 11:48:10 +00:00
Jeff Young 529048dac1 Better error reporting for DP uncoupled length.
Fixes https://gitlab.com/kicad/code/kicad/issues/10087

(cherry picked from commit 722b2588f4)
2022-04-09 23:09:10 +01:00
Jeff Young be2e0cc272 A right-to-left single-char sel followed by typing leaves cursor the same.
Fixes https://gitlab.com/kicad/code/kicad/issues/11349

(cherry picked from commit dead84e7a1)
2022-04-09 21:23:54 +01:00
Jeff Young 48a776f7c5 Repair code that was supposed to be after LoadSymbol().
(Even the comment said so.)

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

(cherry picked from commit ed361925ba)
2022-04-09 21:23:18 +01:00
Jeff Young 43929781a2 On-the-fly translations for pin electrical types.
Also add on-the-fly translation for editor title bars.

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

(cherry picked from commit 68ca385e07)
2022-04-09 21:22:50 +01:00
Seth Hillbrand e02229a234 Don't flag pin missing driver when there is an NC
The NC flag indicates user intention to override the lack of connection
to input pins
2022-04-07 09:29:02 -07:00
Seth Hillbrand 821fe6ea42 Don't set the dirty bit when running DRC
Dirty bit is set in the zone filler separately, there is no action in
the DRC that needs to be saved

Fixes https://gitlab.com/kicad/code/kicad/issues/11344
2022-04-06 17:03:01 -07:00
Seth Hillbrand e740db61f5 Show non-driven error on single-pin nets
Better to have both the single-pin error message and the non-driven
error message when an input pin is not connected than miss error
messages when the pin is connected to a blank net

Fixes https://gitlab.com/kicad/code/kicad/issues/10430
2022-04-06 16:53:23 -07:00
Marek Roszko a700531aba Forcefully ignore PYTHONPATH env variable on Windows
Fix https://gitlab.com/kicad/code/kicad/-/issues/11328


(cherry picked from commit 44296dfea2)
2022-04-05 02:11:32 +00:00
Wayne Stambaugh 7d9cf00fd9 Improve sheet schematic import messages and simplify code.
There was also a logic bug when the selected schematic was in a different
path than the current project and was already part of the current project.
The symbol library table reconciliation code was still run which was wrong.

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

(cherry picked from commit e336a0e403)
2022-04-04 17:19:40 -04:00
jean-pierre charras 6127ae92a5 PLOTTER: do not clamp coordinates to an arbitrary value.
Previously, coordinates were clamped to +- 60 inches. It makes no sense to
clamp them at plotter level: max cooed depends on the editor (schematic/board...)
Rename MAX_PAGE_SIZE_MILS to MAX_PAGE_SIZE_EESCHEMA_MILS and use it only for Eeschema.
Fixes #11196
https://gitlab.com/kicad/code/kicad/issues/11196

(cherry picked from commit 21144481d2)
2022-04-04 13:52:21 -07:00
Jeff Young f8c92e355b Plating thickness appears on both sides of hole wall. 2022-04-04 21:51:30 +01:00
Jeff Young f7f6ea54fe Fix incorrect m_SyncPinEdit setting.
Fixes https://gitlab.com/kicad/code/kicad/issues/11331

(cherry picked from commit 3f9cfc0ac1)
2022-04-04 21:51:30 +01:00
dsa-t fdfe5a813e Clamp cursor to limits of coordinates representation
Also improves large distance handling.

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

(cherry picked from commit 68655540eb)
2022-04-04 13:38:50 -07:00
aris-kimi 636d009860 Added footprint rule area anchors
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10461

(cherry picked from commit 47c0672ff3)
2022-04-04 13:38:00 -07:00
Seth Hillbrand 7d96d5940d UNDEFINED_LAYER is always flashed
This is already true for vias and should be true for pads as well

Fixes https://gitlab.com/kicad/code/kicad/issues/11335
2022-04-04 12:25:55 -07:00
Wayne Stambaugh d3a60f7d83 Fix broken symbol field table editor dialog.
Do not use the symbol field string to populate the value and footprint
grid cells.  The field strings may be empty because the symbol has not
been instantiated yet by entering a sheet.  This fix makes an incorrect
assumption that the first instance value and footprint data in the symbol
is the same for all instances.

Note: this fix is incomplete because the value and footprint fields are
      can now be different between sheet instances.  The entire field
      table editor design will need to be rethought because the current
      grouping doesn't allow different value and footprint instance
      changes.

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

(cherry picked from commit b87fc45e33)
2022-04-04 14:32:07 -04:00
jean-pierre charras 604871518f Export VRML: fix some (minor) issues, from Master branch. 2022-04-04 14:46:55 +02:00
jean-pierre charras 5a68077f60 VRML exporter: make export faster by using SHAPE_POLY_SET::PM_FAST. 2022-04-04 12:28:54 +02:00
Jeff Young 8054f1a948 Apply a more sophisticated test for ignoring isInCoupledDiffPair.
The basic problem is that the DRC engine does length testing and skew
testing by collecting all the diff pair constituent parts and pairing them
itself.  Since each part is collected on its own, we need to ignore the
'B' unit when evaluating any conditional expressions.  However, doing this
in general means that when evaluating "OwnClearance()" we also ignore the
'B' unit and return the diff pair CLEARANCE_CONSTRAINT when we shouldn't.

This implements a more discerning test which know what the current requested
constraint is when evaluating expressions.

See also https://forum.kicad.info/t/solved-custom-differencing-rule-not-working-drc/34034/6

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

(cherry picked from commit f7cdc7af75)
2022-04-03 18:23:41 +01:00
Jeff Young 80bf1048d0 Look for sheet pins inside sheets.
Fixes https://gitlab.com/kicad/code/kicad/issues/11297

(cherry picked from commit 6b99a937d8)
2022-04-03 18:22:15 +01:00
Jeff Young d85e52e9fd A better is-modified test.
Fixes https://gitlab.com/kicad/code/kicad/issues/10791

(cherry picked from commit 09ba7468ae)
2022-04-03 18:21:41 +01:00
Jeff Young e21f0ec9fb Honour prime-event-location when starting router.
Fixes https://gitlab.com/kicad/code/kicad/issues/11239

(cherry picked from commit a54bbfe12b)
2022-04-03 18:21:00 +01:00
Jeff Young 1adfca8f2d Don't re-fetch selection when running select-in-same-sheet.
Fixes https://gitlab.com/kicad/code/kicad/issues/11110

(cherry picked from commit a35ae8cdce)
2022-04-03 18:20:32 +01:00
Jeff Young f89256e51e Implement align-to-grid for sheets.
Fixes https://gitlab.com/kicad/code/kicad/issues/11201

(cherry picked from commit 8dc680adbb)
2022-04-03 18:14:23 +01:00
Jeff Young e98e9f72df Only write Allow DRC Violations if enabled.
Fixes https://gitlab.com/kicad/code/kicad/issues/11177

(cherry picked from commit b78a260326)
2022-04-03 18:13:04 +01:00
Jeff Young f8ff9705ff Fix issues with importing NPTH pads from CircuitStudio.
Fixes https://gitlab.com/kicad/code/kicad/issues/10493

(cherry picked from commit 118a37f19f)
2022-04-03 15:51:33 +01:00
Jeff Young e3e52d055a Don't rely on HasConversion() for Symbol Properties in Symbol Editor.
Fixes https://gitlab.com/kicad/code/kicad/issues/11200

(cherry picked from commit 2681ad6cfc)
2022-04-03 15:51:33 +01:00
Jeff Young 6de8b99cf2 Don't default to Annotate All just because the selection is empty.
Fixes https://gitlab.com/kicad/code/kicad/issues/11181

(cherry picked from commit 6fa8cab188)
2022-04-03 15:51:33 +01:00
Jeff Young c9829cf9a8 Enable bb and/or uvias when encountering them on Altium import.
Fixes https://gitlab.com/kicad/code/kicad/issues/10044

(cherry picked from commit 1d66925f5f)
2022-04-03 15:51:33 +01:00
Jeff Young 0fc4ccf8d9 Clean up pad handling in 3D viewer.
Most importantly, create F_Cu/B_Cu layers if they're otherwise empty
but we have plated pads to render on them.

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

(cherry picked from commit 0dc857b5ab)
2022-04-03 15:51:33 +01:00
Jeff Young 330b1fd733 Don't leave dangling pointers to old document when importing.
This goes for both selection pointers and undo/redo pointers.

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

(cherry picked from commit 535ecb9b7b)
2022-04-03 09:49:37 +01:00
Marek Roszko 455ec428f2 Free memory in dxf import sooner on bad_alloc
(cherry picked from commit b18e441a88)
2022-04-02 13:58:35 +00:00
jean-pierre charras 39959844e5 SYMBOL_EDITOR_CONTROL::DuplicateSymbol(): fix incorrect validation test.
DuplicateSymbol() is called both to duplicate and paste. Only duplicate
needs a test to know if a symbol is selected.
Fixes #11053
https://gitlab.com/kicad/code/kicad/issues/11053
2022-04-02 08:20:27 +02:00
Marek Roszko d5de4bb5c7 Catch memory exhaustion trying to import large DXFs
See https://gitlab.com/kicad/code/kicad/-/issues/11308


(cherry picked from commit 9f8c0a8185)
2022-04-02 03:15:33 +00:00
Seth Hillbrand 6706a5c462 Skip zero-size elements when converting
Also fixes an assertion when converting to polygon from the board editor

Fixes https://gitlab.com/kicad/code/kicad/issues/11313
2022-04-01 13:22:08 -07:00
Seth Hillbrand 15fe2f2fd0 Allow common greek letters in passive regex
Adds common letters (µ and Ω) as prefix and unit

Fixes https://gitlab.com/kicad/code/kicad/issues/11289
2022-04-01 12:51:21 -07:00
Seth Hillbrand c23679d9bd Consistently handle env/prj variables
User-defined variables cannot be used for internally-reserved variables

Fixes https://gitlab.com/kicad/code/kicad/issues/11232
2022-03-31 17:05:25 -07:00
jean-pierre charras f226772938 Cvpcb: fix "not found" .equ files.
Fixes #11264
https://gitlab.com/kicad/code/kicad/issues/11264
2022-03-29 18:54:11 +02:00
Seth Hillbrand 6a53e318e5 Thread the connectivity vector updates
Now that we are dealing with individual connection elements that do not
update their connected elements as well, we can thread the update, just
being careful to guard any remaining updates (bus_enty/busLine) that
need reciprocal updating

Fixes https://gitlab.com/kicad/code/kicad/issues/10974
2022-03-28 15:35:52 -07:00
Seth Hillbrand 776a28a10e Avoid generating SCH_CONNECTION if not needed
If the SCH_ITEM has already been processed, the extra time needed to
iterated over the memberset and get the SCH_CONNECTION when we won't use
it is not neccesary.

Fixes https://gitlab.com/kicad/code/kicad/issues/10974
2022-03-28 15:07:18 -07:00
Seth Hillbrand 3a98eacdb9 Handle connection vector inline
Normally, you will gain by resursing a nested loop only over the
pairs that are not already handled.  In this case, however, you lose
time because you step outside of the cache by adding the reciprocal test
at each step.

Instead, we process one element at a time, keeping it cached and loop
over all other elements to add to the connection.  This saves us about
75% of the time for larger loops (e.g. stacked power pins on a large
BGA)

Fixes https://gitlab.com/kicad/code/kicad/issues/10974
2022-03-28 15:07:18 -07:00
Seth Hillbrand a8004cb161 Update Translations 2022-03-28 11:14:40 -07:00
Henrik Kauhanen f00222b3a6 Translated using Weblate (Swedish)
Currently translated at 99.6% (7186 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-28 19:50:37 +02:00
Mark Hämmerling 96dded48d4 Translated using Weblate (German)
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-03-28 19:50:37 +02:00
Allan Nordhøy 950cccdc1c Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.4% (5295 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/nb_NO/
2022-03-28 19:50:37 +02:00
Mark Hämmerling 5b7a1a8177 Translated using Weblate (German)
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-03-28 19:50:37 +02:00
taotieren 96aa472ff9 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hant/
2022-03-28 19:50:37 +02:00
Henrik Kauhanen 0ec50e9096 Translated using Weblate (Swedish)
Currently translated at 99.4% (7173 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-28 19:50:37 +02:00
Henrik Kauhanen 6bc48e9ca8 Translated using Weblate (Swedish)
Currently translated at 99.4% (7173 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-28 19:50:36 +02:00
Arnau Llovet Vidal 5505add08e Translated using Weblate (Catalan)
Currently translated at 65.7% (4740 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-03-28 19:50:36 +02:00
Marek Roszko 4d8297a1f6 Try and ducktape boost api change for seeder
idk what im doing


(cherry picked from commit d440ff7c37)
2022-03-28 01:48:50 +00:00
Marek Roszko e1cd74dd78 Remove extra boost include
(cherry picked from commit 7a0d8c2fe0)
2022-03-28 01:48:41 +00:00
Mario Luzeiro 2567f45c1d 3D-Viewer: binds the default texture after draw and before end the list
Fixes https://gitlab.com/kicad/code/kicad/issues/2547

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

(cherry picked from commit 7659f3c81b)
2022-03-25 16:22:57 -07:00
Marek Roszko 0ea7dabc12 Read the boost manual right-side up
(cherry picked from commit 3f0f846435)
2022-03-24 22:17:19 +00:00
jean-pierre charras bf8c7d7697 GERBER_JOBFILE_WRITER: fix a crash due to use of a null pointer.
Can happens when it is created from a Python script.
From Master branch
Fixes #11227
https://gitlab.com/kicad/code/kicad/issues/11227
2022-03-24 18:01:24 +01:00
Marek Roszko 891c919c23 Ensure the kiid generator rng is actually uniquely seeded each start
(cherry picked from commit 2e689901fc)
2022-03-23 22:51:33 +00:00
jean-pierre charras 375a7303c5 Gerbview: Fix incorrect rendering of aperture macros combining polygons.
A aperture macro can have polygons with holes, and/or many polygons.
When combining polygons holes can be created. So ensure the resulting polygon
is fractured before drawing it.
From Master branch
Fixes #11218
https://gitlab.com/kicad/code/kicad/issues/11218
2022-03-23 20:56:57 +01:00
jean-pierre charras e14e9cf8a9 PLOTTER: do not clamp coordinates to an arbitrary value.
Previously, coordinates were clamped to +- 60 inches. It makes no sense to
clamp them at plotter level: max coord depends on the editor (schematic/board...)
From Master.
2022-03-23 20:55:25 +01:00
Seth Hillbrand 4e98ce87c7 All triangular trapezoid pads
A triangular trapezoid will have the deltaX/deltaY of the same size as
the length of that axis.  This creates a three-point polygon, which is
perfectly valid for our use
2022-03-22 13:38:36 -07:00
Seth Hillbrand 207820e112 Avoid duplicate points in trapezoid pads
Duplicate points can be either positive-facing or negative facing, so
test absolutes

Fixes https://gitlab.com/kicad/code/kicad/issues/11025
2022-03-22 13:30:22 -07:00
Henrik Kauhanen dbbecefcb9 Translated using Weblate (Swedish)
Currently translated at 99.4% (7173 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-22 19:24:35 +01:00
Wellington Terumi Uemura df8f166847 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-03-22 19:24:35 +01:00
Henrik Kauhanen 79ef8e14aa Translated using Weblate (Swedish)
Currently translated at 99.4% (7173 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-22 19:24:35 +01:00
taotieren 5081165611 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hant/
2022-03-22 19:24:34 +01:00
taotieren 3bfcaf2455 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-03-22 19:24:34 +01:00
Mustafa Selçuk ÇAVDAR 9e2416d2c9 Translated using Weblate (Turkish)
Currently translated at 44.4% (3205 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-03-22 19:24:34 +01:00
boonchai k 49eecf66fe Translated using Weblate (Thai)
Currently translated at 99.6% (7188 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/th/
2022-03-22 19:24:34 +01:00
Henrik Kauhanen bc3a4e4ede Translated using Weblate (Swedish)
Currently translated at 99.4% (7173 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-22 19:24:34 +01:00
Konstantin Baranovskiy 3645c3c0cc Translated using Weblate (Russian)
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ru/
2022-03-22 19:24:34 +01:00
Wellington Terumi Uemura 7902c1cc58 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-03-22 19:24:34 +01:00
ZbeeGin 2a2781e1bc Translated using Weblate (Polish)
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-03-22 19:24:34 +01:00
Tokita, Hiroshi 9510b07807 Translated using Weblate (Japanese)
Currently translated at 99.9% (7204 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-03-22 19:24:34 +01:00
Ulices 072c0f06cd Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7210 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-03-22 19:24:34 +01:00
Eric b75e782aef Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (7209 of 7210 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-03-22 19:24:34 +01:00
Seth Hillbrand d9fe48171b Attempt to fix the Mac DPI grid mixing
When moving windows between monitors on Mac that changes the DPI, we
observe incorrect re-sizing of columns and rows.  This attempts to
rectify the situation by avoiding DPI changes for Mac builds.

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

(cherry picked from commit 9722a05820)
2022-03-22 11:23:49 -07:00
Jeff Young eeee5afdfd Zero out parent rule when overridden by local property.
Fixes https://gitlab.com/kicad/code/kicad/issues/11197

(cherry picked from commit b679a21651)
2022-03-21 20:56:00 +00:00
Jeff Young 790b810621 A little bit of nullptr safety.
Fixes https://gitlab.com/kicad/code/kicad/issues/11077

(cherry picked from commit b3ae0fdca5)
2022-03-21 20:54:28 +00:00
Seth Hillbrand e33bf78d96 Separate flashing check for connectivity
When building the connectivity database, we should not be using the
connectivity to check for shapes.

To make this deterministic, we introduce two flags (ALWAYS_FLASH and
NEVER_FLASH) that are used with connectivity building to determine
whether a pad is flashed for connectivity or not.  ZONE <-> PAD/VIA
connectivity will be checked with ALWAYS_FLASHED and all other
connectivity will be checked with NEVER_FLASHED if they are marked for
potential annular ring removal.  If they are not marked for removal,
they will be checked ALWAYS_FLASHED.

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

(cherry picked from commit 442aae19d9)
2022-03-21 08:37:53 -07:00
jean-pierre charras bd86999615 QA test: fix incorrect call to BOOST_TEST_MESSGE.
It expects a C string, not a wxString.
Fromm Master.
2022-03-21 14:02:18 +01:00
jean-pierre charras 1b108afd0b Specctra import/export: fix some issues (tested only with FreeRouter):
- Handling of locked tracks
- Locked tracks are now exported with attribute "fix".
- Incorrect view cleaning
- Fix memory leak.
From master branch.
2022-03-20 19:05:23 +01:00
jean-pierre charras a8384beb6f Python, board.i: fix incorrect order of an include.
The result was ignoring PCB_SHAPE in pcb_text.i.
2022-03-20 18:47:14 +01:00
Seth Hillbrand c44d31fcfb Fix expand variables for built-in
Allow falling back to the alternate variable definitions if the built-in
text block variables are not set.

Also push the project into variable resolution when plotting

Fixes https://gitlab.com/kicad/code/kicad/issues/11168
2022-03-18 16:46:36 -07:00
Marco Ciampa d801a8689c Updated Italian translation 2022-03-18 21:35:14 +01:00
Frank Zeeman 4a1abd239a Append True to Python 3 AddPrimitivePoly() call
Fixes https://gitlab.com/kicad/code/kicad/issues/11012

(cherry picked from commit b3a319b77e)
2022-03-18 13:01:56 -07:00
Seth Hillbrand 423732910d Update Translations 2022-03-18 12:53:10 -07:00
Arnau Llovet Vidal e4ce5e5262 Translated using Weblate (Catalan)
Currently translated at 65.6% (4737 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-03-18 20:52:12 +01:00
taotieren 2998d31f2c Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (7210 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-03-18 20:52:12 +01:00
Mustafa Selçuk ÇAVDAR da98413f82 Translated using Weblate (Turkish)
Currently translated at 43.9% (3170 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-03-18 20:52:11 +01:00
Bas Wijnen f562466189 Translated using Weblate (Dutch)
Currently translated at 98.4% (7096 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/nl/
2022-03-18 20:52:11 +01:00
김랑기 0deae6bdd2 Translated using Weblate (Korean)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-03-18 20:52:11 +01:00
Mark Hämmerling 31f8e73cf8 Translated using Weblate (German)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-03-18 20:52:11 +01:00
Arnau Llovet Vidal e58f50602d Translated using Weblate (Catalan)
Currently translated at 65.4% (4721 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-03-18 20:52:11 +01:00
Ulices c870505141 Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-03-18 20:52:11 +01:00
Eric c20e81fbdd Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (7210 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-03-18 20:52:11 +01:00
Trần Phi Hải 58d0c4112d Translated using Weblate (Vietnamese)
Currently translated at 17.6% (1271 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/vi/
2022-03-18 20:52:11 +01:00
Henrik Kauhanen 1cb80e1ad0 Translated using Weblate (Swedish)
Currently translated at 99.5% (7175 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-03-18 20:52:11 +01:00
___davidpr 2584c46c28 Translated using Weblate (Serbian)
Currently translated at 13.9% (1006 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sr/
2022-03-18 20:52:11 +01:00
Konstantin Baranovskiy 2ce96415a6 Translated using Weblate (Russian)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ru/
2022-03-18 20:52:10 +01:00
Wellington Terumi Uemura 8eded13d96 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-03-18 20:52:10 +01:00
ZbeeGin 069143dc05 Translated using Weblate (Polish)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-03-18 20:52:10 +01:00
Mark Hämmerling 9d09ce0538 Translated using Weblate (German)
Currently translated at 100.0% (7211 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-03-18 20:52:10 +01:00
Arnau Llovet Vidal d9dd691108 Translated using Weblate (Catalan)
Currently translated at 65.4% (4718 of 7211 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-03-18 20:52:10 +01:00
Jeff Young f69ebe55ad Improved performance for Cleanup Tracks & Vias.
(cherry picked from commit 14378812be)
2022-03-18 12:50:09 -07:00
Jeff Young ff604cc6a3 Pull some fixes back from master.
Mostly wxT(), but also some performance, and some for better response
to Cancel button.

(cherry picked from commit 5c63df28e4)
2022-03-18 12:49:54 -07:00
Jeff Young 8ccc5bd8f2 Special-case synthetic click after tool selection.
Fixes https://gitlab.com/kicad/code/kicad/issues/11057

(cherry picked from commit 1f745b000d)
(cherry picked from commit dd55ffb75c)
2022-03-18 12:49:44 -07:00
Jeff Young 02b1f552fd Make sure LIB_ID escape context allows for formatting constructs.
Also make sure that value field is updated from name changes when the
symbol is a power symbol (even if it's from the schematic instead of
the library).

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

(cherry picked from commit a9eb7a0e28)
(cherry picked from commit 02252be29d)
2022-03-18 12:49:32 -07:00
Wayne Stambaugh f058dc9ed8 Begin version 6.0.5 development. 2022-03-17 19:35:07 -04:00
Wayne Stambaugh 2c061ed67a Tag release version 6.0.4. 2022-03-17 19:33:28 -04:00
Seth Hillbrand 9bfbe3acd8 Revert "Special-case synthetic click after tool selection."
This reverts commit dd55ffb75c.
2022-03-17 16:21:39 -07:00
Seth Hillbrand 40bdd26e39 Revert "Make sure LIB_ID escape context allows for formatting constructs."
This reverts commit 02252be29d.
2022-03-17 16:21:38 -07:00
Seth Hillbrand b0f8055377 Revert "Pull some fixes back from master."
This reverts commit 5c63df28e4.
2022-03-17 16:21:37 -07:00
Seth Hillbrand 33f4fc9873 Revert "Improved performance for Cleanup Tracks & Vias."
This reverts commit 14378812be.
2022-03-17 16:21:34 -07:00
Jeff Young c90842dd08 Update value & footprint from clipboard whether keeping annotation or not.
Fixes https://gitlab.com/kicad/code/kicad/issues/11116

(cherry picked from commit 400cff994d)
2022-03-17 22:34:52 +00:00
Jeff Young 310b4cdf75 Re-entrancy blocker for line/wire/bus tool.
Also clear infobar messages after a cancelInteractive.

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

(cherry picked from commit 05bca282f7)
2022-03-17 22:34:52 +00:00
Seth Hillbrand 2208e0db16 Avoid marking symbols that will not be processed
We want to shorting the processing time by marking symbols that have
already been processed.  But we must avoid marking symbols that will not
be processed due to their other flags

Fixes https://gitlab.com/kicad/code/kicad/issues/11164
2022-03-17 10:10:21 -07:00
jean-pierre charras cf4c403094 Gerber plotter: fix incorrect handling of arcs in polygons.
From master branch.
Fixes #11156
https://gitlab.com/kicad/code/kicad/issues/11156
2022-03-17 13:06:37 +01:00
Jeff Young dd55ffb75c Special-case synthetic click after tool selection.
Fixes https://gitlab.com/kicad/code/kicad/issues/11057

(cherry picked from commit 1f745b000d)
2022-03-16 17:11:07 +00:00
Jeff Young d34faf30cc Save pointer to markers provider.
Fixes https://gitlab.com/kicad/code/kicad/issues/11136

(cherry picked from commit a81c8d4922)
2022-03-16 16:23:10 +00:00
Jeff Young 3720a52ecb Bubble ESC up from the 3D preview.
Fixes https://gitlab.com/kicad/code/kicad/issues/9984

(cherry picked from commit 32fdab8902)
2022-03-16 16:21:24 +00:00
Jeff Young 47de9f8f04 Fix typo which leads to catastrophic performance on boards with tons of zones.
(cherry picked from commit 392a3ec131)
2022-03-16 15:16:11 +00:00
Jeff Young 14378812be Improved performance for Cleanup Tracks & Vias. 2022-03-16 15:15:20 +00:00
Jeff Young 0070a4686e Cherry-pick the short-arc-is-really-a-segment fix from master.
Fixes https://gitlab.com/kicad/code/kicad/issues/11119
2022-03-16 15:15:15 +00:00
Jeff Young 5c63df28e4 Pull some fixes back from master.
Mostly wxT(), but also some performance, and some for better response
to Cancel button.
2022-03-16 15:15:09 +00:00
Jeff Young e5ea37507c Exclude hidden text from selection in FP Editor.
Fixes https://gitlab.com/kicad/code/kicad/issues/11111

(cherry picked from commit 06c1bccccd)
2022-03-16 15:15:01 +00:00
Jeff Young 53bd87d792 Performance fixes for the board from hell....
(cherry picked from commit e4b56ab7f1)
2022-03-16 15:14:51 +00:00
Jeff Young 02252be29d Make sure LIB_ID escape context allows for formatting constructs.
Also make sure that value field is updated from name changes when the
symbol is a power symbol (even if it's from the schematic instead of
the library).

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

(cherry picked from commit a9eb7a0e28)
2022-03-16 15:14:29 +00:00
Wayne Stambaugh 9e9598af5f Begin version 6.0.4 development. 2022-03-15 20:14:40 -04:00
206 changed files with 37139 additions and 35586 deletions
+1 -1
View File
@@ -40,6 +40,6 @@ include:
- local: '/.gitlab/templates.yml'
- local: '/.gitlab/Fedora-Linux-CI.yml'
- local: '/.gitlab/Ubuntu-20.04-CI.yml'
- local: '/.gitlab/Windows-CI.yml'
# - local: '/.gitlab/Windows-CI.yml'
- local: '/.gitlab/coverity.yml'
- local: '/.gitlab/linux-metadata-validate.yml'
@@ -493,15 +493,10 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint,
{
for( PAD* pad : aFootprint->Pads() )
{
if( !pad->IsOnLayer( aLayerId ) )
if( !pad->FlashLayer( aLayerId ) )
continue;
// Skip pad annulus when not connected on this layer (if removing is enabled)
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
continue;
// NPTH pads are not drawn on layers if the
// shape size and pos is the same as their hole:
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
{
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
@@ -526,19 +521,28 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint,
}
}
const bool isPlated = ( ( aLayerId == F_Cu ) && pad->FlashLayer( F_Mask ) ) ||
( ( aLayerId == B_Cu ) && pad->FlashLayer( B_Mask ) );
if( aSkipPlatedPads && isPlated )
continue;
if( aSkipNonPlatedPads && !isPlated )
continue;
wxSize margin( aInflateValue, aInflateValue );
switch( aLayerId )
{
case F_Cu:
if( aSkipPlatedPads && pad->FlashLayer( F_Mask ) )
continue;
if( aSkipNonPlatedPads && !pad->FlashLayer( F_Mask ) )
continue;
break;
case B_Cu:
if( aSkipPlatedPads && pad->FlashLayer( B_Mask ) )
continue;
if( aSkipNonPlatedPads && !pad->FlashLayer( B_Mask ) )
continue;
break;
case F_Mask:
case B_Mask:
margin.x += pad->GetSolderMaskMargin();
+2 -3
View File
@@ -549,7 +549,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
for( FOOTPRINT* footprint : m_board->Footprints() )
{
addPadsWithClearance( footprint, m_platedPadsFront, F_Cu, 0, true, false, true );
addPadsWithClearance( footprint, m_platedPadsBack, B_Cu, 0, true, false, true );
}
@@ -569,8 +568,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// Add pads to polygon list
for( FOOTPRINT* footprint : m_board->Footprints() )
{
// Note: NPTH pads are not drawn on copper layers when the pad
// has same shape as its hole
// Note: NPTH pads are not drawn on copper layers when the pad has same shape as
// its hole
footprint->TransformPadsWithClearanceToPolygon( *layerPoly, curr_layer_id,
0, ARC_HIGH_DEF, ERROR_INSIDE,
true, renderPlatedPadsAsPlated,
+31 -9
View File
@@ -374,6 +374,22 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
}
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayerId )
{
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
getLayerZPos( aLayerId, layer_z_top, layer_z_bot );
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( 1 );
// store in a list so it will be latter deleted
m_triangles.push_back( layerTriangles );
return new OPENGL_RENDER_LIST( *layerTriangles, m_circleTexture, layer_z_bot, layer_z_top );
}
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardPoly,
const BVH_CONTAINER_2D* aThroughHoles )
{
@@ -388,9 +404,8 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardP
if( listBoardObject2d.size() > 0 )
{
// We will set a unitary Z so it will in future used with transformations
// since the board poly will be used not only to draw itself but also the
// solder mask layers.
// We will set a unitary Z so it will in future used with transformations since the
// board poly will be used not only to draw itself but also the solder mask layers.
const float layer_z_top = 1.0f;
const float layer_z_bot = 0.0f;
@@ -563,7 +578,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
const BVH_CONTAINER_2D* container2d = ii.second;
SHAPE_POLY_SET polyListSubtracted;
SHAPE_POLY_SET* aPolyList = nullptr;
SHAPE_POLY_SET* polyList = nullptr;
// Load the vertical (Z axis) component of shapes
@@ -580,9 +595,8 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
{
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract(
m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
}
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) )
@@ -600,10 +614,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
}
}
aPolyList = &polyListSubtracted;
polyList = &polyListSubtracted;
}
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, aPolyList, layer_id,
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer_id,
&m_boardAdapter.GetThroughHoleIds() );
if( oglList != nullptr )
@@ -626,6 +640,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(),
&polySubtracted, F_Cu );
// An entry for F_Cu must exist in m_layers or we'll never look at m_platedPadsFront
if( m_layers.count( F_Cu ) == 0 )
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
}
if( m_boardAdapter.GetBackPlatedPadPolys() )
@@ -640,6 +658,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(),
&polySubtracted, B_Cu );
// An entry for B_Cu must exist in m_layers or we'll never look at m_platedPadsBack
if( m_layers.count( B_Cu ) == 0 )
m_layers[B_Cu] = generateEmptyLayerList( B_Cu );
}
}
@@ -650,6 +650,7 @@ GLuint OPENGL_RENDER_LIST::generate_top_or_bot_seg_ends(
glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
glBindTexture( GL_TEXTURE_2D, 0 );
glDisable( GL_TEXTURE_2D );
glDisable( GL_ALPHA_TEST );
glDisable( GL_BLEND );
@@ -504,7 +504,7 @@ void RENDER_3D_OPENGL::setCopperMaterial()
void RENDER_3D_OPENGL::setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id )
{
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset(-0.1f, -2.0f );
glPolygonOffset( -0.1f, -2.0f );
setLayerMaterial( aLayer_id );
}
@@ -704,18 +704,16 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
{
pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_platedPadsFront || m_platedPadsBack ) )
setPlatedCopperAndDepthOffset( layer_id );
// Draw plated pads
if( layer_id == F_Cu && m_platedPadsFront )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsFront->DrawAllCameraCulled( m_camera.GetPos().z,
drawMiddleSegments );
}
else if( layer_id == B_Cu && m_platedPadsBack )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsBack->DrawAllCameraCulled( m_camera.GetPos().z,
drawMiddleSegments );
}
@@ -751,16 +749,10 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
viasHolesLayer,
m_antiBoard );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_platedPadsFront || m_platedPadsBack ) )
{
setPlatedCopperAndDepthOffset( layer_id );
}
// Draw plated pads
if( layer_id == F_Cu && m_platedPadsFront )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsFront->DrawAllCameraCulledSubtractLayer(
drawMiddleSegments,
m_outerThroughHoles,
@@ -769,6 +761,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
}
else if( layer_id == B_Cu && m_platedPadsBack )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsBack->DrawAllCameraCulledSubtractLayer(
drawMiddleSegments,
m_outerThroughHoles,
@@ -785,21 +778,16 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
m_outerThroughHoles,
m_antiBoard );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_platedPadsFront || m_platedPadsBack ) )
{
setPlatedCopperAndDepthOffset( layer_id );
}
if( layer_id == F_Cu && m_platedPadsFront )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsFront->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
m_outerThroughHoles,
m_antiBoard );
}
else if( layer_id == B_Cu && m_platedPadsBack )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsBack->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
m_outerThroughHoles,
m_antiBoard );
@@ -84,6 +84,8 @@ private:
PCB_LAYER_ID aLayerId,
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayerId );
void addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, const SFVEC2F& v0,
const SFVEC2F& v1, const SFVEC2F& v2, float top, float bot );
@@ -29,6 +29,7 @@
#include <kiface_base.h>
#include <tools/eda_3d_controller.h>
#include "eda_3d_actions.h"
#include "dialogs/panel_preview_3d_model.h"
#include <3d_rendering/opengl/render_3d_opengl.h>
@@ -113,10 +114,36 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
if( evt->IsClick( BUT_RIGHT ) )
if( evt->IsCancelInteractive() )
{
wxWindow* canvas = m_toolMgr->GetToolHolder()->GetToolCanvas();
wxWindow* topLevelParent = canvas->GetParent();
while( topLevelParent && !topLevelParent->IsTopLevel() )
topLevelParent = topLevelParent->GetParent();
if( topLevelParent && dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
{
DIALOG_SHIM* dialog = static_cast<DIALOG_SHIM*>( topLevelParent );
if( dialog->IsQuasiModal() )
dialog->EndQuasiModal( wxID_CANCEL );
else
dialog->EndModal( wxID_CANCEL );
}
else
{
evt->SetPassEvent();
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
else
{
evt->SetPassEvent();
}
}
return 0;
+3 -1
View File
@@ -4,7 +4,7 @@
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -124,8 +124,10 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND, 5 );
for( wxEventType eventType : { wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT } )
{
Connect( eventType, wxMenuEventHandler( PANEL_PREVIEW_3D_MODEL::OnMenuEvent ), nullptr,
this );
}
#ifdef __WXOSX__
// Call layout once to get the proper button sizes after the bitmaps have been set
+5 -3
View File
@@ -848,9 +848,11 @@ if( UNIX AND NOT APPLE AND KICAD_SCRIPTING_WXPYTHON )
endif()
endif()
message( STATUS "Found ${WXPYTHON_FLAVOR} "
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
"(wxWidgets ${WXPYTHON_WXVERSION})" )
if( WXPYTHON_FLAVOR )
message( STATUS "Found wxPython ${WXPYTHON_FLAVOR} "
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
"(wxWidgets ${WXPYTHON_WXVERSION})" )
endif()
#
# Find wxWidgets library, required
+26 -98
View File
@@ -231,11 +231,7 @@ endif()
#=====================================================================
if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Useful common wx libs needed by almost all components.
if(VCPKG_TOOLCHAIN)
set(wxWidgets_COMMON_LIBRARIES libpng16 tiff jpeg zlib libexpat)
else()
set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
endif()
set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
# DEPRECATED: Use find_package(wxWidgets COMPONENTS mono) instead.
if(NOT wxWidgets_FIND_COMPONENTS)
@@ -258,22 +254,24 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
#-------------------------------------------------------------------
#
# Get filename components for a configuration. For example,
# if _CONFIGURATION = mswunivud, then _UNV=univ, _UCD=u _DBG=d
# if _CONFIGURATION = mswu, then _UNV="", _UCD=u _DBG=""
# if _CONFIGURATION = mswunivud, then _PF="msw", _UNV=univ, _UCD=u _DBG=d
# if _CONFIGURATION = mswu, then _PF="msw", _UNV="", _UCD=u _DBG=""
#
macro(WX_GET_NAME_COMPONENTS _CONFIGURATION _UNV _UCD _DBG)
macro(WX_GET_NAME_COMPONENTS _CONFIGURATION _PF _UNV _UCD _DBG)
DBG_MSG_V(${_CONFIGURATION})
string(REGEX MATCH "univ" ${_UNV} "${_CONFIGURATION}")
string(REGEX REPLACE "msw.*(u)[d]*$" "u" ${_UCD} "${_CONFIGURATION}")
string(REGEX REPLACE "[msw|qt].*(u)[d]*$" "u" ${_UCD} "${_CONFIGURATION}")
if(${_UCD} STREQUAL ${_CONFIGURATION})
set(${_UCD} "")
endif()
string(REGEX MATCH "d$" ${_DBG} "${_CONFIGURATION}")
string(REGEX MATCH "^[msw|qt]*" ${_PF} "${_CONFIGURATION}")
endmacro()
#
# Find libraries associated to a configuration.
#
macro(WX_FIND_LIBS _UNV _UCD _DBG)
macro(WX_FIND_LIBS _PF _UNV _UCD _DBG)
DBG_MSG_V("m_unv = ${_UNV}")
DBG_MSG_V("m_ucd = ${_UCD}")
DBG_MSG_V("m_dbg = ${_DBG}")
@@ -286,7 +284,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
NAMES
wx${LIB}${_UCD}${_DBG} # for regex
wx${LIB}${_DBG}
${LIB}${_DBG} # vcpkg libraries aren't specific to wx
PATHS ${WX_LIB_DIR}
NO_DEFAULT_PATH
)
@@ -326,13 +323,13 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets monolithic library.
find_library(WX_mono${_DBG}
NAMES
wxmsw${_UNV}31${_UCD}${_DBG}
wxmsw${_UNV}30${_UCD}${_DBG}
wxmsw${_UNV}29${_UCD}${_DBG}
wxmsw${_UNV}28${_UCD}${_DBG}
wxmsw${_UNV}27${_UCD}${_DBG}
wxmsw${_UNV}26${_UCD}${_DBG}
wxmsw${_UNV}25${_UCD}${_DBG}
wx${_PF}${_UNV}31${_UCD}${_DBG}
wx${_PF}${_UNV}30${_UCD}${_DBG}
wx${_PF}${_UNV}29${_UCD}${_DBG}
wx${_PF}${_UNV}28${_UCD}${_DBG}
wx${_PF}${_UNV}27${_UCD}${_DBG}
wx${_PF}${_UNV}26${_UCD}${_DBG}
wx${_PF}${_UNV}25${_UCD}${_DBG}
PATHS ${WX_LIB_DIR}
NO_DEFAULT_PATH
)
@@ -340,16 +337,16 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets multilib libraries.
foreach(LIB core adv aui html media xrc dbgrid gl qa richtext
webview stc ribbon propgrid)
stc ribbon propgrid webview)
find_library(WX_${LIB}${_DBG}
NAMES
wxmsw${_UNV}31${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}30${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}29${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}28${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}27${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}26${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}25${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}31${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}30${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}29${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}28${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}27${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}26${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}25${_UCD}${_DBG}_${LIB}
PATHS ${WX_LIB_DIR}
NO_DEFAULT_PATH
)
@@ -515,74 +512,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
set(WX_LIB_DIR_PREFIX vc)
endif()
if(VCPKG_TOOLCHAIN)
set(wxWidgets_FOUND TRUE)
find_path(wxWidgets_ROOT_DIR
NAMES include/wx/wx.h
PATHS
ENV wxWidgets_ROOT_DIR
DOC "wxWidgets base/installation directory"
)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(wxWidgets_LIB_DIR ${wxWidgets_ROOT_DIR}/debug/lib)
set(wxWidgets_CONFIGURATION mswud)
else()
set(wxWidgets_LIB_DIR ${wxWidgets_ROOT_DIR}/lib)
set(wxWidgets_CONFIGURATION mswu)
endif()
set(wxWidgets_BIN_DIR ${wxWidgets_ROOT_DIR}/bin)
set(wxWidgets_INCLUDE_DIR ${wxWidgets_ROOT_DIR}/include)
file(GLOB DLL ${wxWidgets_BIN_DIR}/wxmsw*.dll)
if (DLL)
set(wxWidgets_DEFINITIONS WXUSINGDLL)
DBG_MSG_V("detected SHARED/DLL tree wxWidgets_LIB_DIR=${wxWidgets_LIB_DIR}")
endif ()
set(WX_ROOT_DIR ${wxWidgets_ROOT_DIR})
set(WX_LIB_DIR ${wxWidgets_LIB_DIR}) # needed by macro
set(WX_CONFIGURATION_LIST ${wxWidgets_CONFIGURATION})
# Set wxWidgets lib setup include directory.
if (EXISTS ${wxWidgets_INCLUDE_DIR}/wx/setup.h)
set(wxWidgets_INCLUDE_DIRS ${wxWidgets_INCLUDE_DIR})
else ()
DBG_MSG("wxWidgets_FOUND FALSE because ${wxWidgets_INCLUDE_DIR}/wx/setup.h does not exists.")
set(wxWidgets_FOUND FALSE)
endif ()
# Set wxWidgets main include directory.
if (EXISTS ${wxWidgets_ROOT_DIR}/include/wx/wx.h)
list(APPEND wxWidgets_INCLUDE_DIRS ${wxWidgets_ROOT_DIR}/include)
else ()
DBG_MSG("wxWidgets_FOUND FALSE because wxWidgets_ROOT_DIR=${wxWidgets_ROOT_DIR} has no ${wxWidgets_ROOT_DIR}/include/wx/wx.h")
set(wxWidgets_FOUND FALSE)
endif ()
DBG_MSG_V("WX_CONFIGURATION_LIST=${WX_CONFIGURATION_LIST}")
# Get configuration parameters from the name.
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} UNV UCD DBG)
# Find wxWidgets libraries.
WX_FIND_LIBS("${UNV}" "${UCD}" "${DBG}")
if (WX_USE_REL_AND_DBG)
WX_FIND_LIBS("${UNV}" "${UCD}" "d")
endif ()
# Settings for requested libs (i.e., include dir, libraries, etc.).
WX_SET_LIBRARIES(wxWidgets_FIND_COMPONENTS "${DBG}")
# Add necessary definitions for unicode builds
if ("${UCD}" STREQUAL "u")
list(APPEND wxWidgets_DEFINITIONS UNICODE _UNICODE)
endif ()
# Add necessary definitions for debug builds
set(wxWidgets_DEFINITIONS_DEBUG _DEBUG __WXDEBUG__)
else()
if(BUILD_SHARED_LIBS)
find_path(wxWidgets_LIB_DIR
NAMES
@@ -617,7 +546,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
DOC "Path to wxWidgets libraries"
NO_DEFAULT_PATH
)
endif()
endif()
# If wxWidgets_LIB_DIR changed, clear all libraries.
@@ -675,7 +603,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
endif()
# Get configuration parameters from the name.
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} UNV UCD DBG)
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} PF UNV UCD DBG)
# Set wxWidgets lib setup include directory.
if(EXISTS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h)
@@ -695,9 +623,9 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
endif()
# Find wxWidgets libraries.
WX_FIND_LIBS("${UNV}" "${UCD}" "${DBG}")
WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "${DBG}")
if(WX_USE_REL_AND_DBG)
WX_FIND_LIBS("${UNV}" "${UCD}" "d")
WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "d")
endif()
# Settings for requested libs (i.e., include dir, libraries, etc.).
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "6.0.3" )
set( KICAD_SEMANTIC_VERSION "6.0.5" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
-1
View File
@@ -158,7 +158,6 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
wxMemoryInputStream is( data, count );
wxImage image( is, wxBITMAP_TYPE_PNG );
wxBitmap bitmap( image );
return image;
}
+1 -2
View File
@@ -152,9 +152,8 @@ wxString DS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
}
else if( m_titleBlock )
{
m_titleBlock->TextVarResolver( token, m_project );
// no need for tokenUpdated; TextVarResolver() did a full resolve
return true;
return m_titleBlock->TextVarResolver( token, m_project );
}
if( tokenUpdated )
+1 -1
View File
@@ -694,7 +694,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
void EDA_DRAW_FRAME::UpdateMsgPanel()
{
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
GetToolManager()->ProcessEvent( EVENTS::SelectedItemsModified );
}
+1
View File
@@ -320,6 +320,7 @@ static struct EDA_ITEM_DESC
.Map( PCB_FP_SHAPE_T, _HKI( "Graphic" ) )
.Map( PCB_FP_ZONE_T, _HKI( "Zone" ) )
.Map( PCB_TRACE_T, _HKI( "Track" ) )
.Map( PCB_ARC_T, _HKI( "Track" ) )
.Map( PCB_VIA_T, _HKI( "Via" ) )
.Map( PCB_MARKER_T, _HKI( "Marker" ) )
.Map( PCB_DIM_ALIGNED_T, _HKI( "Dimension" ) )
+13 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -165,6 +165,18 @@ void FILE_HISTORY::doAddClearItem( wxMenu* aMenu )
}
void FILE_HISTORY::UpdateClearText( wxMenu* aMenu, wxString aClearText )
{
size_t itemPos;
wxMenuItem* clearItem = aMenu->FindChildItem( m_clearId, &itemPos );
if( clearItem && itemPos > 1 ) // clearItem is the last menu, after a separator
{
clearItem->SetItemLabel( aClearText );
}
}
void FILE_HISTORY::ClearFileHistory()
{
while( GetCount() > 0 )
+8 -2
View File
@@ -40,8 +40,14 @@
// boost:mt19937 is not thread-safe
static std::mutex rng_mutex;
// Create only once, as seeding is *very* expensive
static boost::mt19937 rng;
// Static rng and generators are used because the overhead of constant seeding is expensive
// We break out the rng separately from the generator because we want to control seeding in cases like unit tests
#if BOOST_VERSION >= 106700
static boost::uuids::detail::random_provider seeder; // required to ensure the rng has a random initial seed
#else
static boost::uuids::detail::seed_rng seeder; // required to ensure the rng has a random initial seed
#endif
static boost::mt19937 rng( seeder );
static boost::uuids::basic_random_generator<boost::mt19937> randomGenerator( rng );
// These don't have the same performance penalty, but we might as well be consistent
+11 -17
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -842,18 +842,6 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
wxPoint start( aArc.GetP0() );
wxPoint end( aArc.GetP1() );
wxPoint center( aArc.GetCenter() );
double startAngle = aArc.GetStartAngle();
double endAngle = aArc.GetEndAngle();
if( startAngle > endAngle )
{
if( endAngle < 0.0 )
endAngle = NormalizeAnglePos( endAngle ) ;
else
{
startAngle = NormalizeAnglePos( startAngle ) - 3600.0;
}
}
if( !aPlotInRegion )
MoveTo( start);
@@ -861,14 +849,20 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
LineTo( start );
DPOINT devEnd = userToDeviceCoordinates( end );
DPOINT devCenter = userToDeviceCoordinates( center ) - userToDeviceCoordinates( start );
DPOINT devCenter = userToDeviceCoordinates( center - start );
VECTOR2I arcMidPoint = aArc.GetArcMid();
// We need to know if the arc is CW or CCW in device coordinates, so build this arc.
SHAPE_ARC deviceArc( userToDeviceCoordinates( start ),
userToDeviceCoordinates( wxPoint( arcMidPoint.x, arcMidPoint.y ) ),
devEnd, 0 );
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
if( startAngle > endAngle )
fprintf( m_outputFile, "G03*\n" ); // Active circular interpolation, CCW
else
if( deviceArc.IsClockwise() )
fprintf( m_outputFile, "G02*\n" ); // Active circular interpolation, CW
else
fprintf( m_outputFile, "G03*\n" ); // Active circular interpolation, CCW
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
-6
View File
@@ -93,12 +93,6 @@ DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& aCoordinate )
{
wxPoint pos = aCoordinate - m_plotOffset;
// Don't allow overflows; they can cause rendering failures in some file viewers
// (such as Acrobat)
int clampSize = MAX_PAGE_SIZE_MILS * m_IUsPerDecimil * 10 / 2;
pos.x = std::max( -clampSize, std::min( pos.x, clampSize ) );
pos.y = std::max( -clampSize, std::min( pos.y, clampSize ) );
double x = pos.x * m_plotScale;
double y = ( m_paperSize.y - pos.y * m_plotScale );
+9 -7
View File
@@ -538,18 +538,20 @@ EDIMENSION::EDIMENSION( wxXmlNode* aDimension )
y2 %Coord; #REQUIRED
x3 %Coord; #REQUIRED
y3 %Coord; #REQUIRED
textsize %Coord;
layer %Layer; #REQUIRED
dtype %DimensionType; "parallel"
>
*/
x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
}
+14 -14
View File
@@ -531,13 +531,13 @@ struct EJUNCTION
/// Eagle label
struct ELABEL
{
ECOORD x;
ECOORD y;
ECOORD size;
LAYER_NUM layer;
opt_erot rot;
ECOORD x;
ECOORD y;
ECOORD size;
LAYER_NUM layer;
opt_erot rot;
opt_wxString xref;
wxString netname;
wxString netname;
ELABEL( wxXmlNode* aLabel, const wxString& aNetName );
};
@@ -619,14 +619,14 @@ struct EATTR
/// Eagle dimension element
struct EDIMENSION
{
ECOORD x1;
ECOORD y1;
ECOORD x2;
ECOORD y2;
ECOORD x3;
ECOORD y3;
int layer;
ECOORD x1;
ECOORD y1;
ECOORD x2;
ECOORD y2;
ECOORD x3;
ECOORD y3;
opt_ecoord textsize;
int layer;
opt_wxString dimensionType;
EDIMENSION( wxXmlNode* aDimension );
+7 -1
View File
@@ -37,6 +37,8 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
m_te( aScintilla ),
m_braces( aBraces ),
m_lastCaretPos( -1 ),
m_lastSelStart( -1 ),
m_lastSelEnd( -1 ),
m_suppressAutocomplete( false ),
m_singleLine( aSingleLine ),
m_returnCallback( aReturnCallback )
@@ -337,10 +339,14 @@ void SCINTILLA_TRICKS::onScintillaUpdateUI( wxStyledTextEvent& aEvent )
// Has the caret changed position?
int caretPos = m_te->GetCurrentPos();
int selStart = m_te->GetSelectionStart();
int selEnd = m_te->GetSelectionEnd();
if( m_lastCaretPos != caretPos )
if( m_lastCaretPos != caretPos || m_lastSelStart != selStart || m_lastSelEnd != selEnd )
{
m_lastCaretPos = caretPos;
m_lastSelStart = selStart;
m_lastSelEnd = selEnd;
int bracePos1 = -1;
int bracePos2 = -1;
+12 -2
View File
@@ -142,7 +142,15 @@ bool ConvertSmartQuotesAndDashes( wxString* aString )
wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
{
wxString converted;
wxString converted;
std::vector<bool> braceStack; // true == formatting construct
auto hasFormattingPrefix =
[&]()
{
static wxString prefixes = wxT( "~_^" );
return !converted.IsEmpty() && prefixes.Find( converted.Last() ) >= 0;
};
converted.reserve( aSource.length() );
@@ -159,7 +167,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
}
else if( aContext == CTX_LIBID )
{
if( c == '{' )
if( c == '{' && !hasFormattingPrefix() )
converted += wxT( "{brace}" );
else if( c == '/' )
converted += wxT( "{slash}" );
@@ -227,7 +235,9 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
converted += c;
}
else
{
converted += c;
}
}
return converted;
+5 -6
View File
@@ -183,21 +183,20 @@ wxMenuItem* ACTION_MENU::Add( const TOOL_ACTION& aAction, bool aIsCheckmarkEntry
wxMenuItem* ACTION_MENU::Add( ACTION_MENU* aMenu )
{
ACTION_MENU* menuCopy = aMenu->Clone();
m_submenus.push_back( menuCopy );
m_submenus.push_back( aMenu );
wxASSERT_MSG( !menuCopy->m_title.IsEmpty(), wxT( "Set a title for ACTION_MENU using SetTitle()" ) );
wxASSERT_MSG( !aMenu->m_title.IsEmpty(), wxT( "Set a title for ACTION_MENU using SetTitle()" ) );
if( !!aMenu->m_icon )
{
wxMenuItem* newItem = new wxMenuItem( this, -1, menuCopy->m_title );
wxMenuItem* newItem = new wxMenuItem( this, -1, aMenu->m_title );
AddBitmapToMenuItem( newItem, KiBitmap( aMenu->m_icon ) );
newItem->SetSubMenu( menuCopy );
newItem->SetSubMenu( aMenu );
return Append( newItem );
}
else
{
return AppendSubMenu( menuCopy, menuCopy->m_title );
return AppendSubMenu( aMenu, aMenu->m_title );
}
}
+1 -1
View File
@@ -150,7 +150,7 @@ void CONDITIONAL_MENU::Evaluate( SELECTION& aSelection )
case ENTRY::MENU:
entry.Menu()->UpdateTitle();
Add( entry.Menu() );
Add( entry.Menu()->Clone() );
menu_count++;
break;
+23 -15
View File
@@ -36,6 +36,7 @@
#include <trace_helpers.h>
#include <settings/common_settings.h>
#include <math/util.h> // for KiROUND
#include <geometry/geometry_utils.h>
#include <widgets/ui_common.h>
#include <class_draw_panel_gal.h>
#include <kiplatform/ui.h>
@@ -300,7 +301,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
}
if( m_updateCursor ) // do not update the cursor position if it was explicitly set
m_cursorPos = m_view->ToWorld( mousePos );
m_cursorPos = GetClampedCoords( m_view->ToWorld( mousePos ) );
else
m_updateCursor = true;
@@ -648,7 +649,7 @@ VECTOR2D WX_VIEW_CONTROLS::GetMousePosition( bool aWorldCoordinates ) const
wxPoint msp = getMouseScreenPosition();
VECTOR2D screenPos( msp.x, msp.y );
return aWorldCoordinates ? m_view->ToWorld( screenPos ) : screenPos;
return aWorldCoordinates ? GetClampedCoords( m_view->ToWorld( screenPos ) ) : screenPos;
}
@@ -675,7 +676,7 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition( bool aEnableSnapping ) const
}
else
{
return GetRawCursorPosition( aEnableSnapping );
return GetClampedCoords( GetRawCursorPosition( aEnableSnapping ) );
}
}
@@ -685,10 +686,12 @@ void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpV
{
m_updateCursor = false;
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
if( aTriggeredByArrows )
{
m_settings.m_lastKeyboardCursorPositionValid = true;
m_settings.m_lastKeyboardCursorPosition = aPosition;
m_settings.m_lastKeyboardCursorPosition = clampedPosition;
m_settings.m_lastKeyboardCursorCommand = aArrowCommand;
m_cursorWarped = false;
}
@@ -700,8 +703,8 @@ void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpV
m_cursorWarped = true;
}
WarpCursor( aPosition, true, aWarpView );
m_cursorPos = aPosition;
WarpCursor( clampedPosition, true, aWarpView );
m_cursorPos = clampedPosition;
}
@@ -710,14 +713,16 @@ void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition,
{
m_updateCursor = false;
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
VECTOR2D screenPos = m_view->ToScreen( aPosition );
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
if( aWarpView && !screen.Contains( screenPos ) )
m_view->SetCenter( aPosition );
m_view->SetCenter( clampedPosition );
m_cursorPos = aPosition;
m_cursorPos = clampedPosition;
}
@@ -727,14 +732,15 @@ void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordin
if( aWorldCoordinates )
{
const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
VECTOR2D screenPos = m_view->ToScreen( aPosition );
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
if( !screen.Contains( screenPos ) )
{
if( aWarpView )
{
m_view->SetCenter( aPosition );
m_view->SetCenter( clampedPosition );
m_parentPanel->WarpPointer( screenSize.x / 2, screenSize.y / 2 );
}
}
@@ -889,7 +895,7 @@ void WX_VIEW_CONTROLS::refreshMouse()
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
m_cursorPos = m_view->ToWorld( VECTOR2D( msp.x, msp.y ) );
m_cursorPos = GetClampedCoords( m_view->ToWorld( VECTOR2D( msp.x, msp.y ) ) );
wxPostEvent( m_parentPanel, moveEvent );
}
@@ -943,6 +949,8 @@ void WX_VIEW_CONTROLS::UpdateScrollbars()
void WX_VIEW_CONTROLS::ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition )
{
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
m_settings.m_forceCursorPosition = aEnabled;
m_settings.m_forcedPosition = aPosition;
m_settings.m_forcedPosition = clampedPosition;
}
+21
View File
@@ -40,6 +40,11 @@ WX_GRID::WX_GRID( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxS
// Make sure the GUI font scales properly on GTK
SetDefaultCellFont( KIUI::GetControlFont( this ) );
#if wxCHECK_VERSION( 3, 1, 0 )
Connect( wxEVT_DPI_CHANGED, wxDPIChangedEventHandler( WX_GRID::onDPIChanged ), nullptr, this );
#endif
}
@@ -47,9 +52,25 @@ WX_GRID::~WX_GRID()
{
if( m_weOwnTable )
DestroyTable( GetTable() );
#if wxCHECK_VERSION( 3, 1, 0 )
Disconnect( wxEVT_DPI_CHANGED, wxDPIChangedEventHandler( WX_GRID::onDPIChanged ), nullptr, this );
#endif
}
#if wxCHECK_VERSION( 3, 1, 0 )
void WX_GRID::onDPIChanged(wxDPIChangedEvent& aEvt)
{
/// This terrible hack is a way to avoid the incredibly disruptive resizing of grids that happens on Macs
/// when moving a window between monitors of different DPIs.
#ifndef __WXMAC__
aEvt.Skip();
#endif
}
#endif
void WX_GRID::SetColLabelSize( int aHeight )
{
if( aHeight == 0 )
+6 -4
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -94,7 +94,10 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList,
{
fn = wxExpandEnvVars( equfile );
tmp = search.FindValidPath( fn.GetFullPath() );
if( fn.IsAbsolute() || fn.FileExists() )
tmp = fn.GetFullPath();
else
tmp = search.FindValidPath( fn.GetFullPath() );
if( !tmp )
{
@@ -102,8 +105,7 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList,
if( aErrorMessages )
{
error_msg.Printf( _( "Equivalence file '%s' could not be found in the "
"default search paths." ),
error_msg.Printf( _( "Equivalence file '%s' could not be found." ),
fn.GetFullName() );
if( ! aErrorMessages->IsEmpty() )
+138 -95
View File
@@ -588,112 +588,140 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
// Pre-scan to see if we have a bus at this location
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
for( auto primary_it = connection_vec.begin(); primary_it != connection_vec.end(); primary_it++ )
// We don't want to spin up a new thread for fewer than 4 items (overhead costs)
size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
( connection_vec.size() + 3 ) / 4 );
std::atomic<size_t> nextItem( 0 );
std::mutex update_mutex;
std::vector<std::future<size_t>> returns( parallelThreadCount );
auto update_lambda = [&]() -> size_t
{
SCH_ITEM* connected_item = *primary_it;
// Bus entries are special: they can have connection points in the
// middle of a wire segment, because the junction algo doesn't split
// the segment in two where you place a bus entry. This means that
// bus entries that don't land on the end of a line segment need to
// have "virtual" connection points to the segments they graphically
// touch.
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
for( size_t ii = nextItem++; ii < connection_vec.size(); ii = nextItem++ )
{
// If this location only has the connection point of the bus
// entry itself, this means that either the bus entry is not
// connected to anything graphically, or that it is connected to
// a segment at some point other than at one of the endpoints.
if( connection_vec.size() == 1 )
{
if( busLine )
{
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
bus_entry->m_connected_bus_item = busLine;
}
}
}
// Bus-to-bus entries are treated just like bus wires
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
{
if( connection_vec.size() < 2 )
{
if( busLine )
{
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
if( it.first == bus_entry->GetPosition() )
bus_entry->m_connected_bus_items[0] = busLine;
else
bus_entry->m_connected_bus_items[1] = busLine;
bus_entry->AddConnectionTo( aSheet, busLine );
busLine->AddConnectionTo( aSheet, bus_entry );
}
}
}
// Change junctions to be on bus junction layer if they are touching a bus
else if( connected_item->Type() == SCH_JUNCTION_T )
{
connected_item->SetLayer( busLine ? LAYER_BUS_JUNCTION : LAYER_JUNCTION );
}
for( auto test_it = primary_it + 1; test_it != connection_vec.end(); test_it++ )
{
bool bus_connection_ok = true;
SCH_ITEM* test_item = *test_it;
wxASSERT( test_item != connected_item );
// Set up the link between the bus entry net and the bus
SCH_ITEM* connected_item = connection_vec[ii];
// Bus entries are special: they can have connection points in the
// middle of a wire segment, because the junction algo doesn't split
// the segment in two where you place a bus entry. This means that
// bus entries that don't land on the end of a line segment need to
// have "virtual" connection points to the segments they graphically
// touch.
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
if( test_item->GetLayer() == LAYER_BUS )
// If this location only has the connection point of the bus
// entry itself, this means that either the bus entry is not
// connected to anything graphically, or that it is connected to
// a segment at some point other than at one of the endpoints.
if( connection_vec.size() == 1 )
{
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
bus_entry->m_connected_bus_item = test_item;
if( busLine )
{
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
bus_entry->m_connected_bus_item = busLine;
}
}
}
// Bus entries only connect to bus lines on the end that is touching a bus line.
// If the user has overlapped another net line with the endpoint of the bus entry
// where the entry connects to a bus, we don't want to short-circuit it.
// Bus-to-bus entries are treated just like bus wires
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
{
if( connection_vec.size() < 2 )
{
if( busLine )
{
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
if( it.first == bus_entry->GetPosition() )
bus_entry->m_connected_bus_items[0] = busLine;
else
bus_entry->m_connected_bus_items[1] = busLine;
std::lock_guard<std::mutex> lock( update_mutex );
bus_entry->AddConnectionTo( aSheet, busLine );
busLine->AddConnectionTo( aSheet, bus_entry );
}
}
}
// Change junctions to be on bus junction layer if they are touching a bus
else if( connected_item->Type() == SCH_JUNCTION_T )
{
connected_item->SetLayer( busLine ? LAYER_BUS_JUNCTION : LAYER_JUNCTION );
}
SCH_ITEM_SET& connected_set = connected_item->ConnectedItems( aSheet );
connected_set.reserve( connection_vec.size() );
for( SCH_ITEM* test_item : connection_vec )
{
bool bus_connection_ok = true;
if( test_item == connected_item )
continue;
// Set up the link between the bus entry net and the bus
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
if( test_item->GetLayer() == LAYER_BUS )
{
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
bus_entry->m_connected_bus_item = test_item;
}
}
// Bus entries only connect to bus lines on the end that is touching a bus line.
// If the user has overlapped another net line with the endpoint of the bus entry
// where the entry connects to a bus, we don't want to short-circuit it.
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
bus_connection_ok = !busLine || test_item->GetLayer() == LAYER_BUS;
}
else if( test_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
}
if( connected_item->ConnectionPropagatesTo( test_item ) &&
test_item->ConnectionPropagatesTo( connected_item ) &&
bus_connection_ok )
{
connected_set.push_back( test_item );
}
}
// If we got this far and did not find a connected bus item for a bus entry,
// we should do a manual scan in case there is a bus item on this connection
// point but we didn't pick it up earlier because there is *also* a net item here.
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
bus_connection_ok = !busLine || test_item->GetLayer() == LAYER_BUS;
}
else if( test_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
}
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
if( connected_item->ConnectionPropagatesTo( test_item ) &&
test_item->ConnectionPropagatesTo( connected_item ) &&
bus_connection_ok )
{
connected_item->AddConnectionTo( aSheet, test_item );
test_item->AddConnectionTo( aSheet, connected_item );
if( !bus_entry->m_connected_bus_item )
{
SCH_SCREEN* screen = aSheet.LastScreen();
SCH_LINE* bus = screen->GetBus( it.first );
if( bus )
bus_entry->m_connected_bus_item = bus;
}
}
}
// If we got this far and did not find a connected bus item for a bus entry,
// we should do a manual scan in case there is a bus item on this connection
// point but we didn't pick it up earlier because there is *also* a net item here.
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
return 1;
};
if( !bus_entry->m_connected_bus_item )
{
SCH_SCREEN* screen = aSheet.LastScreen();
SCH_LINE* bus = screen->GetBus( it.first );
if( bus )
bus_entry->m_connected_bus_item = bus;
}
}
if( parallelThreadCount == 1 )
update_lambda();
else
{
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii] = std::async( std::launch::async, update_lambda );
// Finalize the threads
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii].wait();
}
}
}
@@ -730,12 +758,12 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
SCH_CONNECTION* conn = aItem->GetOrInitConnection( sheet, this );
bool unique = !( aItem->GetFlags() & CANDIDATE );
aItem->SetFlags( CANDIDATE );
if( conn && !conn->SubgraphCode() )
aItem->SetFlags( CANDIDATE );
return ( unique && conn && ( conn->SubgraphCode() == 0 ) );
};
std::copy_if( item->ConnectedItems( sheet ).begin(),
item->ConnectedItems( sheet ).end(),
std::back_inserter( memberlist ), get_items );
@@ -754,10 +782,16 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
connected_conn->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[connected_item] = subgraph;
subgraph->AddItem( connected_item );
SCH_ITEM_SET citemset = connected_item->ConnectedItems( sheet );
SCH_ITEM_SET& citemset = connected_item->ConnectedItems( sheet );
std::copy_if( citemset.begin(), citemset.end(),
std::back_inserter( memberlist ), get_items );
for( SCH_ITEM* citem : citemset )
{
if( citem->HasFlag( CANDIDATE ) )
continue;
if( get_items( citem ) )
memberlist.push_back( citem );
}
}
}
@@ -1332,8 +1366,13 @@ void CONNECTION_GRAPH::buildConnectionGraph()
m_bus_alias_cache[ alias->GetName() ] = alias;
}
PROF_TIMER sub_graph( "buildItemSubGraphs" );
buildItemSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
sub_graph.Show();
/**
* TODO(JE): Net codes are non-deterministic. Fortunately, they are also not really used for
* anything. We should consider removing them entirely and just using net names everywhere.
@@ -1345,8 +1384,12 @@ void CONNECTION_GRAPH::buildConnectionGraph()
generateInvisiblePinSubGraphs();
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
processSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
proc_sub_graph.Show();
// Absorbed subgraphs should no longer be considered
alg::delete_if( m_driver_subgraphs, [&]( const CONNECTION_SUBGRAPH* candidate ) -> bool
{
+1 -1
View File
@@ -396,7 +396,7 @@ void DIALOG_ERC::testErc()
|| settings.IsTestEnabled( ERCE_POWERPIN_NOT_DRIVEN )
|| settings.IsTestEnabled( ERCE_PIN_NOT_DRIVEN ) )
{
tester.TestPinToPin();
tester.TestPinToPin();
}
// Test similar labels (i;e. labels which are identical when
@@ -30,6 +30,7 @@
#include <sch_line.h>
#include <sch_junction.h>
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <advanced_config.h>
#include <tool/tool_manager.h>
@@ -412,6 +413,12 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
if( m_setBgColor->GetValue() )
sheet->SetBackgroundColor( m_bgColorSwatch->GetSwatchColor() );
}
if( m_sheetPins->GetValue() )
{
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
processItem( aSheetPath, pin );
}
}
else if( aItem->Type() == SCH_JUNCTION_T )
{
@@ -439,8 +446,6 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
processItem( aSheetPath, aItem );
else if( m_hierLabels->GetValue() && aItem->Type() == SCH_HIER_LABEL_T )
processItem( aSheetPath, aItem );
else if( m_sheetPins->GetValue() && aItem->Type() == SCH_SHEET_PIN_T )
processItem( aSheetPath, aItem );
else if( m_schTextAndGraphics->GetValue() && aItem->IsType( schTextAndGraphics ) )
processItem( aSheetPath, aItem );
}
@@ -75,10 +75,10 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataToWindow()
bool enblConvOptStyle = symbol && symbol->HasConversion();
// if a symbol contains no graphic items, symbol->HasConversion() returns false.
// but when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions
// must be enabled even if symbol->HasConversion() returns false in order to be able
// to create graphic items shared by all body styles
// If a symbol contains no conversion-specific pins or graphic items, symbol->HasConversion()
// will return false.
// But when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions
// must be enabled in order to be able to create graphic items shared by all body styles.
if( m_frame->GetShowDeMorgan() )
enblConvOptStyle = true;
@@ -174,7 +174,13 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
m_SelNumberOfUnits->SetValue( m_libEntry->GetUnitCount() );
m_OptionPartsInterchangeable->SetValue( !m_libEntry->UnitsLocked() ||
m_libEntry->GetUnitCount() == 1 );
m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
// If a symbol contains no conversion-specific pins or graphic items, symbol->HasConversion()
// will return false. But when editing a symbol with DeMorgan option set, we don't want to
// keep turning it off just because there aren't any conversion-specific items yet, so we force
// it to on if the parent frame has it enabled.
m_AsConvertButt->SetValue( m_Parent->GetShowDeMorgan() );
m_OptionPower->SetValue( m_libEntry->IsPower() );
m_excludeFromBomCheckBox->SetValue( !m_libEntry->GetIncludeInBom() );
m_excludeFromBoardCheckBox->SetValue( !m_libEntry->GetIncludeOnBoard() );
@@ -367,6 +373,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
m_libEntry->LockUnits( m_libEntry->GetUnitCount() > 1 &&
!m_OptionPartsInterchangeable->GetValue() );
m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
m_Parent->SetShowDeMorgan( m_AsConvertButt->GetValue() );
if( m_OptionPower->GetValue() )
m_libEntry->SetPower();
@@ -448,7 +455,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
void DIALOG_LIB_SYMBOL_PROPERTIES::OnSymbolNameText( wxCommandEvent& event )
{
if( !m_Parent->IsSymbolFromSchematic() )
if( !m_Parent->IsSymbolFromSchematic() || m_OptionPower->IsChecked() )
m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
}
+9 -1
View File
@@ -1250,7 +1250,15 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
wxStandardPaths::Get().GetDocumentsDir() );
// Build the absolute path of current output directory to preselect it in the file browser.
wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool
{
return m_parent->Schematic().ResolveTextVar( token, 0 );
};
wxString path = m_outputDirectoryName->GetValue();
path = ExpandTextVars( path, &textResolver, nullptr, &Prj() );
path = ExpandEnvVarSubstitutions( path, &Prj() );
fn.SetPath( path );
@@ -208,8 +208,17 @@ public:
for( unsigned i = 0; i < m_symbolsList.GetCount(); ++i )
{
SCH_SYMBOL* symbol = m_symbolsList[ i ].GetSymbol();
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = symbol->GetFieldText( aFieldName,
m_frame );
wxCHECK( symbol && ( symbol->GetInstanceReferences().size() != 0 ), /* void */ );
wxString val = symbol->GetFieldText( aFieldName, m_frame );
if( aFieldName == wxT( "Value" ) )
val = symbol->GetInstanceReferences()[0].m_Value;
else if( aFieldName == wxT( "Footprint" ) )
val = symbol->GetInstanceReferences()[0].m_Footprint;
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = val;
}
}
+5 -5
View File
@@ -439,9 +439,13 @@ int ERC_TESTER::TestPinToPin()
{
std::vector<SCH_PIN*> pins;
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
bool has_noconnect = false;
for( CONNECTION_SUBGRAPH* subgraph: net.second )
{
if( subgraph->m_no_connect )
has_noconnect = true;
for( EDA_ITEM* item : subgraph->m_items )
{
if( item->Type() == SCH_PIN_T )
@@ -452,10 +456,6 @@ int ERC_TESTER::TestPinToPin()
}
}
// Single-pin nets are handled elsewhere
if( pins.size() < 2 )
continue;
std::set<std::pair<SCH_PIN*, SCH_PIN*>> tested;
SCH_PIN* needsDriver = nullptr;
@@ -542,7 +542,7 @@ int ERC_TESTER::TestPinToPin()
}
}
if( needsDriver && !hasDriver )
if( needsDriver && !hasDriver && !has_noconnect )
{
int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
+1 -1
View File
@@ -502,7 +502,7 @@ void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue
value = fn.GetFullPath();
}
}
else if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) && aRow == VALUE_FIELD )
else if( m_parentType == SCH_SYMBOL_T && aRow == VALUE_FIELD )
{
value = EscapeString( value, CTX_LIBID );
}
+4 -2
View File
@@ -632,6 +632,10 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
if( dlg.ShowModal() == wxID_CANCEL )
return;
// Don't leave dangling pointers to previously-opened document.
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
ClearUndoRedoList();
if( setProject )
{
Schematic().SetProject( nullptr );
@@ -665,8 +669,6 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
return;
}
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
importFile( dlg.GetPath(), pluginType );
RefreshCanvas();
+19 -7
View File
@@ -214,15 +214,20 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
if( m_me == aRhs.m_me )
return 0;
int retv = m_name.Cmp( aRhs.m_name );
int retv = 0;
if( retv )
return retv;
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
{
retv = m_name.Cmp( aRhs.m_name );
retv = m_libId.compare( aRhs.m_libId );
if( retv )
return retv;
if( retv )
return retv;
retv = m_libId.compare( aRhs.m_libId );
if( retv )
return retv;
}
if( m_parent.lock() < aRhs.m_parent.lock() )
return -1;
@@ -258,8 +263,15 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
{
const LIB_FIELD* lhsField = static_cast<const LIB_FIELD*>( lhsItem );
if( lhsField->IsMandatory() )
if( lhsField->GetId() == VALUE_FIELD )
{
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 || IsPower() )
retv = lhsItem->compare( *rhsItem, aCompareFlags );
}
else if( lhsField->IsMandatory() )
{
retv = lhsItem->compare( *rhsItem, aCompareFlags );
}
}
else
{
+5 -2
View File
@@ -62,17 +62,20 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
if( !openRecentMenu )
{
openRecentMenu = new ACTION_MENU( false, selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( BITMAPS::recent );
fileHistory.UseMenu( openRecentMenu );
fileHistory.AddFilesToMenu( openRecentMenu );
}
// Ensure the title is up to date after changing language
openRecentMenu->SetTitle( _( "Open Recent" ) );
fileHistory.UpdateClearText( openRecentMenu, _( "Clear Recent Files" ) );
fileMenu->Add( ACTIONS::doNew );
fileMenu->Add( ACTIONS::open );
wxMenuItem* item = fileMenu->Add( openRecentMenu );
wxMenuItem* item = fileMenu->Add( openRecentMenu->Clone() );
// Add the file menu condition here since it needs the item ID for the submenu
ACTION_CONDITIONS cond;
@@ -209,12 +209,12 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceFieldDefVal( SPICE_FIELD aField, SCH_S
wxString value = aSymbol->GetField( VALUE_FIELD )->GetShownText();
// Is it a passive component?
if( aCtl & NET_ADJUST_PASSIVE_VALS && ( prim == 'C' || prim == 'L' || prim == 'R' ) )
if( ( aCtl & NET_ADJUST_PASSIVE_VALS ) && ( prim == 'C' || prim == 'L' || prim == 'R' ) )
{
// Regular expression to match common formats used for passive parts description
// (e.g. 100k, 2k3, 1 uF)
wxRegEx passiveVal(
"^([0-9\\. ]+)([fFpPnNuUmMkKgGtT]|M(e|E)(g|G))?([fFhH]|ohm)?([-1-9 ]*)$" );
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
if( passiveVal.Matches( value ) )
{
+11 -13
View File
@@ -25,9 +25,8 @@
#include "pin_numbers.h"
#include <wx/crt.h>
namespace {
wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
wxString PIN_NUMBERS::getNextSymbol( const wxString& str, wxString::size_type& cursor )
{
if( str.size() <= cursor )
return wxEmptyString;
@@ -36,14 +35,15 @@ wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
wxChar c = str[cursor];
if( wxIsdigit( c ) || c == '+' || c == '-' )
// Need to check that there is a digit in the string before we parse it as a numeric
if( ( wxIsdigit( c ) || ( ( c == '+' || c == '-' ) && ( cursor < str.size() - 1 ) && wxIsdigit( str[cursor + 1] ) ) ) )
{
// number, possibly with sign
while( ++cursor < str.size() )
{
c = str[cursor];
if( wxIsdigit( c ) || c == 'v' || c == 'V' )
if( wxIsdigit( c ) || c == 'v' || c == 'V' || c == '.' )
continue;
else
break;
@@ -65,8 +65,6 @@ wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
return str.substr( begin, cursor - begin );
}
}
wxString PIN_NUMBERS::GetSummary() const
{
@@ -117,8 +115,8 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
for( ; ; )
{
symbol1 = GetNextSymbol( lhs, cursor1 );
symbol2 = GetNextSymbol( rhs, cursor2 );
symbol1 = getNextSymbol( lhs, cursor1 );
symbol2 = getNextSymbol( rhs, cursor2 );
if( symbol1.empty() && symbol2.empty() )
return 0;
@@ -129,12 +127,12 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
if( symbol2.empty() )
return 2;
wxChar c1 = symbol1[0];
wxChar c2 = symbol2[0];
bool sym1_isnumeric = symbol1.find_first_of( "0123456789" ) != wxString::npos;
bool sym2_isnumeric = symbol2.find_first_of( "0123456789" ) != wxString::npos;
if( wxIsdigit( c1 ) || c1 == '-' || c1 == '+' )
if( sym1_isnumeric )
{
if( wxIsdigit( c2 ) || c2 == '-' || c2 == '+' )
if( sym2_isnumeric )
{
// numeric comparison
wxString::size_type v1 = symbol1.find_first_of( wxT( "vV" ) );
@@ -173,7 +171,7 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
}
else
{
if( wxIsdigit( c2 ) || c2 == '-' || c2 == '+' )
if( sym2_isnumeric )
return 2;
int res = symbol1.Cmp( symbol2 );
+2
View File
@@ -47,6 +47,8 @@ private:
typedef std::set<wxString, less> container_type;
static wxString getNextSymbol( const wxString& str, wxString::size_type& cursor );
public:
typedef container_type::value_type value_type;
typedef container_type::iterator iterator;
+29 -8
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,6 +26,7 @@
#include <core/arraydim.h>
#include <lib_pin.h>
#include <pin_type.h>
#include "pgm_base.h"
// These are true singletons so it's OK for them to be globals.
@@ -46,8 +47,8 @@ struct pinTypeStruct
BITMAPS bitmap;
};
// clang-format off
const std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> pinTypes = {
std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinTypes = {
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
@@ -61,7 +62,9 @@ const std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> pinTypes = {
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
};
// clang-format on
int g_pinTypesLanguage = wxLANGUAGE_UNKNOWN;
struct pinShapeStruct
@@ -236,9 +239,27 @@ const std::vector<BITMAPS>& PinOrientationIcons()
wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
{
auto findIt = pinTypes.find( aType );
if( g_pinTypesLanguage != Pgm().GetSelectedLanguageIdentifier() )
{
g_pinTypes[ELECTRICAL_PINTYPE::PT_INPUT].name = _( "Input" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OUTPUT].name = _( "Output" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_BIDI].name = _( "Bidirectional" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_TRISTATE].name = _( "Tri-state" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_PASSIVE].name = _( "Passive" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_NIC].name = _( "Free" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_UNSPECIFIED].name = _( "Unspecified" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_IN].name = _( "Power input" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_OUT].name = _( "Power output" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR].name = _( "Open collector" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENEMITTER].name = _( "Open emitter" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_NC].name = _( "Unconnected" );
wxCHECK_MSG( findIt != pinTypes.end(), wxT( "???" ), "Could not find pin type in lookup map" );
g_pinTypesLanguage = Pgm().GetSelectedLanguageIdentifier();
}
auto findIt = g_pinTypes.find( aType );
wxCHECK_MSG( findIt != g_pinTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
return findIt->second.name;
}
@@ -246,9 +267,9 @@ wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
BITMAPS ElectricalPinTypeGetBitmap( ELECTRICAL_PINTYPE aType )
{
auto findIt = pinTypes.find( aType );
auto findIt = g_pinTypes.find( aType );
wxCHECK_MSG( findIt != pinTypes.end(), BITMAPS::INVALID_BITMAP,
wxCHECK_MSG( findIt != g_pinTypes.end(), BITMAPS::INVALID_BITMAP,
wxT( "Could not find pin type in lookup map" ) );
return findIt->second.bitmap;
+2
View File
@@ -1502,6 +1502,8 @@ void SCH_EDIT_FRAME::ShowChangedLanguage()
// status bar
UpdateMsgPanel();
UpdateTitle();
// This ugly hack is to fix an option(left) toolbar update bug that seems to only affect
// windows. See https://bugs.launchpad.net/kicad/+bug/1816492. For some reason, calling
// wxWindow::Refresh() does not resolve the issue. Only a resize event seems to force the
+4 -4
View File
@@ -1013,10 +1013,10 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
c = getRenderColor( aPin, LAYER_HIDDEN, drawingShadows );
}
float insideOffset = textOffset - thickness[INSIDE] / 2.0;
float outsideOffset = 2 * Mils2iu( PIN_TEXT_MARGIN ) - thickness[OUTSIDE] / 2.0;
float aboveOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[ABOVE] + penWidth ) / 2.0;
float belowOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[BELOW] + penWidth ) / 2.0;
float insideOffset = textOffset - thickness[INSIDE] / 2.0;
float outsideOffset = Mils2iu( PIN_TEXT_MARGIN ) + TARGET_PIN_RADIUS - thickness[OUTSIDE] / 2.0;
float aboveOffset = Mils2iu( PIN_TEXT_MARGIN ) + penWidth / 2.0 + thickness[ABOVE] / 2.0;
float belowOffset = Mils2iu( PIN_TEXT_MARGIN ) + penWidth / 2.0 + thickness[BELOW] / 2.0;
if( isDangling )
outsideOffset += TARGET_PIN_RADIUS / 2.0;
@@ -1308,6 +1308,13 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
SYMDEF_SCM symbol = Library.SymbolDefinitions.at( aSymdefID );
int gateNumber = getKiCadUnitNumberFromGate( aGateID );
// Ensure there are no items on this unit (e.g. if we already previously loaded the symbol from
// the part definition)
std::vector<LIB_ITEM*> drawItems = aSymbol->GetUnitDrawItems( gateNumber, 0 );
for( LIB_ITEM* item : drawItems )
aSymbol->RemoveDrawItem( item );
for( std::pair<FIGURE_ID, FIGURE> figPair : symbol.Figures )
{
FIGURE fig = figPair.second;
@@ -1569,15 +1569,15 @@ void SCH_SEXPR_PARSER::parsePAGE_INFO( PAGE_INFO& aPageInfo )
// Perform some controls to avoid crashes if the size is edited by hands
if( width < MIN_PAGE_SIZE_MILS )
width = MIN_PAGE_SIZE_MILS;
else if( width > MAX_PAGE_SIZE_MILS )
width = MAX_PAGE_SIZE_MILS;
else if( width > MAX_PAGE_SIZE_EESCHEMA_MILS )
width = MAX_PAGE_SIZE_EESCHEMA_MILS;
int height = Mm2mils( parseDouble( "height" ) ); // height stored in mm so we convert to mils
if( height < MIN_PAGE_SIZE_MILS )
height = MIN_PAGE_SIZE_MILS;
else if( height > MAX_PAGE_SIZE_MILS )
height = MAX_PAGE_SIZE_MILS;
else if( height > MAX_PAGE_SIZE_EESCHEMA_MILS )
height = MAX_PAGE_SIZE_EESCHEMA_MILS;
aPageInfo.SetWidthMils( width );
aPageInfo.SetHeightMils( height );
+25 -4
View File
@@ -237,6 +237,27 @@ void SCH_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
}
bool SCH_SYMBOL::IsMovableFromAnchorPoint() const
{
// If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is
// going to end up moving the symbol's pins off-grid.
// The minimal grid size allowed to place a pin is 25 mils
const int min_grid_size = Mils2iu( 25 );
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
{
if( ( ( pin->GetPosition().x - m_pos.x ) % min_grid_size ) != 0 )
return false;
if( ( ( pin->GetPosition().y - m_pos.y ) % min_grid_size ) != 0 )
return false;
}
return true;
}
void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
{
if( m_lib_id != aLibId )
@@ -604,9 +625,9 @@ void SCH_SYMBOL::SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue )
{
if( sheet == nullptr )
{
// Clear instance overrides and set primary field value
// Set all instances to the updated value
for( SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
instance.m_Value = wxEmptyString;
instance.m_Value = aValue;
m_fields[ VALUE_FIELD ].SetText( aValue );
return;
@@ -655,9 +676,9 @@ void SCH_SYMBOL::SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFoo
{
if( sheet == nullptr )
{
// Clear instance overrides and set primary field value
// Set all instances to new footprint value
for( SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
instance.m_Footprint = wxEmptyString;
instance.m_Footprint = aFootprint;
m_fields[ FOOTPRINT_FIELD ].SetText( aFootprint );
return;
+3 -2
View File
@@ -138,9 +138,10 @@ public:
* they are big. However, this annoyed some users and we now have a preference which
* controls warping on move in general, so this was switched to true for symbols.
*
* @return true for a symbol.
* @note We now use this to keep poorly-formed symbols from getting dragged off-grid. If
* the symbol contains off-grid pins we will not allow it to be moved from its anchor.
*/
bool IsMovableFromAnchorPoint() const override { return true; }
bool IsMovableFromAnchorPoint() const override;
void SetLibId( const LIB_ID& aName );
+1 -1
View File
@@ -50,7 +50,7 @@ SCH_VIEW::SCH_VIEW( bool aIsDynamic, SCH_BASE_FRAME* aFrame ) :
// Set m_boundary to define the max working area size. The default value is acceptable for
// Pcbnew and Gerbview, but too large for Eeschema due to very different internal units.
// A full size = 3 * MAX_PAGE_SIZE_MILS size allows a wide margin around the drawing-sheet.
double max_size = Mils2iu( MAX_PAGE_SIZE_MILS ) * 3.0;
double max_size = Mils2iu( MAX_PAGE_SIZE_EESCHEMA_MILS ) * 3.0;
m_boundary.SetOrigin( -max_size/4, -max_size/4 );
m_boundary.SetSize( max_size, max_size );
}
+192 -189
View File
@@ -206,229 +206,232 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
wxMessageDialog::ButtonLabel okButtonLabel( _( "Continue Load" ) );
wxMessageDialog::ButtonLabel cancelButtonLabel( _( "Cancel Load" ) );
if( fileName.GetPathWithSep() == Prj().GetProjectPath()
&& !prjScreens.HasSchematic( fullFilename ) )
if( !prjScreens.HasSchematic( fullFilename ) )
{
// A schematic in the current project path that isn't part of the current project.
// It's possible the user copied this schematic from another project so the library
// links may not be available. Even this is check is no guarantee that all symbol
// library links are valid but it's better than nothing.
for( const wxString& name : names )
if( fileName.GetPathWithSep() == Prj().GetProjectPath() )
{
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
newLibNames.Add( name );
}
if( !newLibNames.IsEmpty() )
{
msg = _( "There are library names in the loaded schematic that are missing "
"from the project library table. This may result in broken symbol "
"library links for the loaded schematic. Do you wish to continue?" );
wxMessageDialog msgDlg3( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg3.ShowModal() == wxID_CANCEL )
return false;
}
}
else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
{
// A schematic loaded from a path other than the current project path.
// If there are symbol libraries in the imported schematic that are not in the
// symbol library table of this project, there could be a lot of broken symbol
// library links. Attempt to add the missing libraries to the project symbol
// library table.
wxArrayString duplicateLibNames;
for( const wxString& name : names )
{
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
newLibNames.Add( name );
else
duplicateLibNames.Add( name );
}
SYMBOL_LIB_TABLE table;
wxFileName symLibTableFn( fileName.GetPath(),
SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
// If there are any new or duplicate libraries, check to see if it's possible that
// there could be any missing libraries that would cause broken symbol library links.
if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
{
if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
// A schematic in the current project path that isn't part of the current project.
// It's possible the user copied this schematic from another project so the library
// links may not be available. Even this is check is no guarantee that all symbol
// library links are valid but it's better than nothing.
for( const wxString& name : names )
{
msg.Printf( _( "The project library table '%s' does not exist or cannot "
"be read. This may result in broken symbol links for the "
"schematic. Do you wish to continue?" ),
symLibTableFn.GetFullPath() );
wxMessageDialog msgDlg4( this, msg, _( "Continue Load Schematic" ),
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
newLibNames.Add( name );
}
if( !newLibNames.IsEmpty() )
{
msg = _( "There are library names in the selected schematic that are missing "
"from the current project library table. This may result in broken "
"symbol library references for the loaded schematic.\n\n"
"Do you wish to continue?" );
wxMessageDialog msgDlg3( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg4.ShowModal() == wxID_CANCEL )
if( msgDlg3.ShowModal() == wxID_CANCEL )
return false;
}
else
{
try
{
table.Load( symLibTableFn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error loading the symbol library table '%s'." ),
symLibTableFn.GetFullPath() );
DisplayErrorMessage( nullptr, msg, ioe.What() );
return false;
}
}
}
// Check to see if any of the symbol libraries found in the appended schematic do
// not exist in the current project are missing from the appended project symbol
// library table.
if( !newLibNames.IsEmpty() )
else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
{
bool missingLibNames = table.IsEmpty();
// A schematic loaded from a path other than the current project path.
if( !missingLibNames )
// If there are symbol libraries in the imported schematic that are not in the
// symbol library table of this project, there could be a lot of broken symbol
// library links. Attempt to add the missing libraries to the project symbol
// library table.
wxArrayString duplicateLibNames;
for( const wxString& name : names )
{
for( const wxString& newLibName : newLibNames )
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
newLibNames.Add( name );
else
duplicateLibNames.Add( name );
}
SYMBOL_LIB_TABLE table;
wxFileName symLibTableFn( fileName.GetPath(),
SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
// If there are any new or duplicate libraries, check to see if it's possible that
// there could be any missing libraries that would cause broken symbol library links.
if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
{
if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
{
if( !table.HasLibrary( newLibName ) )
msg = _( "The selected file was created as part of a different project. "
"Linking the file to this project may result in missing or "
"incorrect symbol library references.\n\n"
"Do you wish to continue?" );
wxMessageDialog msgDlg4( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg4.ShowModal() == wxID_CANCEL )
return false;
}
else
{
try
{
missingLibNames = true;
break;
table.Load( symLibTableFn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error loading the symbol library table '%s'." ),
symLibTableFn.GetFullPath() );
DisplayErrorMessage( nullptr, msg, ioe.What() );
return false;
}
}
}
if( missingLibNames )
// Check to see if any of the symbol libraries found in the appended schematic do
// not exist in the current project are missing from the appended project symbol
// library table.
if( !newLibNames.IsEmpty() )
{
msg = _( "There are library names in the loaded schematic that are missing "
"from the loaded schematic project library table. This may result "
"in broken symbol library links for the schematic. "
"Do you wish to continue?" );
wxMessageDialog msgDlg5( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
bool missingLibNames = table.IsEmpty();
if( msgDlg5.ShowModal() == wxID_CANCEL )
return false;
}
}
// The library name already exists in the current project. Check to see if the
// duplicate name is the same library in the current project. If it's not, it's
// most likely that the symbol library links will be broken.
if( !duplicateLibNames.IsEmpty() && !table.IsEmpty() )
{
bool libNameConflict = false;
for( const wxString& duplicateLibName : duplicateLibNames )
{
const SYMBOL_LIB_TABLE_ROW* thisRow = nullptr;
const SYMBOL_LIB_TABLE_ROW* otherRow = nullptr;
if( Prj().SchSymbolLibTable()->HasLibrary( duplicateLibName ) )
thisRow = Prj().SchSymbolLibTable()->FindRow( duplicateLibName );
if( table.HasLibrary( duplicateLibName ) )
otherRow = table.FindRow( duplicateLibName );
// It's in the global library table so there is no conflict.
if( thisRow && !otherRow )
continue;
if( !thisRow || !otherRow )
continue;
wxFileName otherUriFileName;
wxString thisURI = thisRow->GetFullURI( true );
wxString otherURI = otherRow->GetFullURI( false);
if( otherURI.Contains( wxT( "${KIPRJMOD}" ) ) || otherURI.Contains( wxT( "$(KIPRJMOD)" ) ) )
if( !missingLibNames )
{
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
// not expand to a valid symbol library path.
otherUriFileName.SetPath( fileName.GetPath() );
otherUriFileName.SetFullName( otherURI.AfterLast( '}' ) );
otherURI = otherUriFileName.GetFullPath();
for( const wxString& newLibName : newLibNames )
{
if( !table.HasLibrary( newLibName ) )
{
missingLibNames = true;
break;
}
}
}
if( thisURI != otherURI )
if( missingLibNames )
{
libNameConflict = true;
break;
msg = _( "There are symbol library names in the selected schematic that "
"are missing from the selected schematic project library table. "
"This may result in broken symbol library references.\n\n"
"Do you wish to continue?" );
wxMessageDialog msgDlg5( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg5.ShowModal() == wxID_CANCEL )
return false;
}
}
if( libNameConflict )
// The library name already exists in the current project. Check to see if the
// duplicate name is the same library in the current project. If it's not, it's
// most likely that the symbol library links will be broken.
if( !duplicateLibNames.IsEmpty() && !table.IsEmpty() )
{
msg = _( "A duplicate library name that references a different library exists "
"in the current library table. This conflict cannot be resolved and "
"may result in broken symbol library links for the schematic. "
"Do you wish to continue?" );
wxMessageDialog msgDlg6( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
bool libNameConflict = false;
if( msgDlg6.ShowModal() == wxID_CANCEL )
return false;
for( const wxString& duplicateLibName : duplicateLibNames )
{
const SYMBOL_LIB_TABLE_ROW* thisRow = nullptr;
const SYMBOL_LIB_TABLE_ROW* otherRow = nullptr;
if( Prj().SchSymbolLibTable()->HasLibrary( duplicateLibName ) )
thisRow = Prj().SchSymbolLibTable()->FindRow( duplicateLibName );
if( table.HasLibrary( duplicateLibName ) )
otherRow = table.FindRow( duplicateLibName );
// It's in the global library table so there is no conflict.
if( thisRow && !otherRow )
continue;
if( !thisRow || !otherRow )
continue;
wxFileName otherUriFileName;
wxString thisURI = thisRow->GetFullURI( true );
wxString otherURI = otherRow->GetFullURI( false);
if( otherURI.Contains( "${KIPRJMOD}" ) || otherURI.Contains( "$(KIPRJMOD)" ) )
{
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
// not expand to a valid symbol library path.
otherUriFileName.SetPath( fileName.GetPath() );
otherUriFileName.SetFullName( otherURI.AfterLast( '}' ) );
otherURI = otherUriFileName.GetFullPath();
}
if( thisURI != otherURI )
{
libNameConflict = true;
break;
}
}
if( libNameConflict )
{
msg = _( "A duplicate library name that references a different library exists "
"in the current library table. This conflict cannot be resolved and "
"may result in broken symbol library references.\n\n"
"Do you wish to continue?" );
wxMessageDialog msgDlg6( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
wxCENTER | wxICON_QUESTION );
msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg6.ShowModal() == wxID_CANCEL )
return false;
}
}
}
// All (most?) of the possible broken symbol library link cases are covered. Map the
// new appended schematic project symbol library table entries to the current project
// symbol library table.
if( !newLibNames.IsEmpty() && !table.IsEmpty() )
{
for( const wxString& libName : newLibNames )
// All (most?) of the possible broken symbol library link cases are covered. Map the
// new appended schematic project symbol library table entries to the current project
// symbol library table.
if( !newLibNames.IsEmpty() && !table.IsEmpty() )
{
if( !table.HasLibrary( libName )
|| Prj().SchSymbolLibTable()->HasLibrary( libName ) )
for( const wxString& libName : newLibNames )
{
continue;
if( !table.HasLibrary( libName )
|| Prj().SchSymbolLibTable()->HasLibrary( libName ) )
{
continue;
}
// Don't expand environment variable because KIPRJMOD will not be correct
// for a different project.
wxString uri = table.GetFullURI( libName, false );
wxFileName newLib;
if( uri.Contains( "${KIPRJMOD}" ) || uri.Contains( "$(KIPRJMOD)" ) )
{
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
// not expand to a valid symbol library path.
newLib.SetPath( fileName.GetPath() );
newLib.SetFullName( uri.AfterLast( '}' ) );
uri = newLib.GetFullPath();
}
else
{
uri = table.GetFullURI( libName );
}
// Add the library from the imported project to the current project
// symbol library table.
const SYMBOL_LIB_TABLE_ROW* row = table.FindRow( libName );
wxCHECK( row, false );
SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( libName, uri,
row->GetType(),
row->GetOptions(),
row->GetDescr() );
Prj().SchSymbolLibTable()->InsertRow( newRow );
libTableChanged = true;
}
// Don't expand environment variable because KIPRJMOD will not be correct
// for a different project.
wxString uri = table.GetFullURI( libName, false );
wxFileName newLib;
if( uri.Contains( wxT( "${KIPRJMOD}" ) ) || uri.Contains( wxT( "$(KIPRJMOD)" ) ) )
{
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
// not expand to a valid symbol library path.
newLib.SetPath( fileName.GetPath() );
newLib.SetFullName( uri.AfterLast( '}' ) );
uri = newLib.GetFullPath();
}
else
{
uri = table.GetFullURI( libName );
}
// Add the library from the imported project to the current project
// symbol library table.
const SYMBOL_LIB_TABLE_ROW* row = table.FindRow( libName );
wxCHECK( row, false );
SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( libName, uri,
row->GetType(),
row->GetOptions(),
row->GetDescr() );
Prj().SchSymbolLibTable()->InsertRow( newRow );
libTableChanged = true;
}
}
}
+15 -4
View File
@@ -375,10 +375,11 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
return IsSymbolEditable() && !IsSymbolAlias();
};
auto libModifiedCondition =
auto symbolModifiedCondition =
[this]( const SELECTION& sel )
{
return m_libMgr->HasModifications();
return m_libMgr->IsSymbolModified( GetTargetLibId().GetLibItemName(),
GetTargetLibId().GetLibNickname() );
};
auto libSelectedCondition =
@@ -408,7 +409,7 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( ACTIONS::undo, ENABLE( haveSymbolCond && cond.UndoAvailable() ) );
mgr->SetConditions( ACTIONS::redo, ENABLE( haveSymbolCond && cond.RedoAvailable() ) );
mgr->SetConditions( ACTIONS::revert, ENABLE( haveSymbolCond && libModifiedCondition ) );
mgr->SetConditions( ACTIONS::revert, ENABLE( symbolModifiedCondition ) );
mgr->SetConditions( ACTIONS::toggleGrid, CHECK( cond.GridVisible() ) );
mgr->SetConditions( ACTIONS::toggleCursorStyle, CHECK( cond.FullscreenCursor() ) );
@@ -813,7 +814,9 @@ SYMBOL_LIBRARY_MANAGER& SYMBOL_EDIT_FRAME::GetLibManager()
void SYMBOL_EDIT_FRAME::OnModify()
{
GetScreen()->SetContentModified();
storeCurrentSymbol();
if( !IsSymbolFromSchematic() )
storeCurrentSymbol();
m_treePane->GetLibTree()->RefreshLibTree();
@@ -1136,6 +1139,14 @@ void SYMBOL_EDIT_FRAME::ShowChangedLanguage()
// status bar
UpdateMsgPanel();
if( GetRenderSettings()->m_ShowPinsElectricalType )
{
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
GetCanvas()->Refresh();
}
updateTitle();
}
+55 -23
View File
@@ -234,14 +234,33 @@ bool SYMBOL_EDIT_FRAME::saveCurrentSymbol()
{
if( GetCurSymbol() )
{
LIB_ID libId = GetCurSymbol()->GetLibId();
const wxString& libName = libId.GetLibNickname();
const wxString& symbolName = libId.GetLibItemName();
if( m_libMgr->FlushSymbol( symbolName, libName ) )
if( IsSymbolFromSchematic() )
{
m_libMgr->ClearSymbolModified( symbolName, libName );
return true;
SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
if( !schframe ) // happens when the schematic editor has been closed
{
DisplayErrorMessage( this, _( "No schematic currently open." ) );
return false;
}
else
{
schframe->SaveSymbolToSchematic( *m_symbol, m_schematicSymbolUUID );
GetScreen()->SetContentModified( false );
return true;
}
}
else
{
LIB_ID libId = GetCurSymbol()->GetLibId();
const wxString& libName = libId.GetLibNickname();
const wxString& symbolName = libId.GetLibItemName();
if( m_libMgr->FlushSymbol( symbolName, libName ) )
{
m_libMgr->ClearSymbolModified( symbolName, libName );
return true;
}
}
}
@@ -251,14 +270,15 @@ bool SYMBOL_EDIT_FRAME::saveCurrentSymbol()
bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aConvert )
{
if( !IsSymbolFromSchematic()
&& GetCurSymbol() && GetCurSymbol()->GetLibId() == aLibId
&& GetUnit() == aUnit && GetConvert() == aConvert )
if( GetCurSymbol() && !IsSymbolFromSchematic()
&& GetCurSymbol()->GetLibId() == aLibId
&& GetUnit() == aUnit
&& GetConvert() == aConvert )
{
return true;
}
if( GetScreen()->IsContentModified() && GetCurSymbol() )
if( GetCurSymbol() && IsSymbolFromSchematic() && GetScreen()->IsContentModified() )
{
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
[&]() -> bool
@@ -318,7 +338,7 @@ bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, in
return false;
// Enable synchronized pin edit mode for symbols with interchangeable units
m_SyncPinEdit = !GetCurSymbol()->UnitsLocked();
m_SyncPinEdit = GetCurSymbol()->IsMulti() && !GetCurSymbol()->UnitsLocked();
ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
@@ -489,10 +509,6 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol()
new_symbol.LockUnits( false );
new_symbol.SetConversion( dlg.GetAlternateBodyStyle() );
// must be called after loadSymbol, that calls SetShowDeMorgan, but
// because the symbol is empty,it looks like it has no alternate body
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
}
else
{
@@ -540,6 +556,10 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol()
m_libMgr->UpdateSymbol( &new_symbol, lib );
SyncLibraries( false );
LoadSymbol( name, lib, 1 );
// must be called after loadSymbol, that calls SetShowDeMorgan, but
// because the symbol is empty,it looks like it has no alternate body
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
}
@@ -749,9 +769,12 @@ void SYMBOL_EDIT_FRAME::UpdateAfterSymbolProperties( wxString* aOldName )
RebuildSymbolUnitsList();
SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
updateTitle();
// N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
// the view pointers by rebuilting the field table
RebuildView();
UpdateMsgPanel();
RebuildView();
OnModify();
}
@@ -986,16 +1009,25 @@ void SYMBOL_EDIT_FRAME::RevertAll()
void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
{
if( GetCurSymbol() && IsSymbolFromSchematic() && GetScreen()->IsContentModified() )
{
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
[&]() -> bool
{
return saveCurrentSymbol();
} ) )
{
return;
}
}
LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
if( !symbol )
{
wxString msg;
msg.Printf( _( "Symbol %s not found in library '%s'." ),
aAlias,
aLibrary );
DisplayError( this, msg );
DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
aAlias,
aLibrary ) );
return;
}
+32 -10
View File
@@ -22,9 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "sch_drawing_tools.h"
#include "ee_selection_tool.h"
#include "ee_grid_helper.h"
#include <tools/sch_drawing_tools.h>
#include <tools/ee_selection_tool.h>
#include <tools/ee_grid_helper.h>
#include <ee_actions.h>
#include <sch_edit_frame.h>
#include <project.h>
@@ -192,6 +192,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( symbol )
{
cleanup();
@@ -430,6 +432,8 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( image )
{
cleanup();
@@ -983,6 +987,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
SCH_ITEM* item = nullptr;
KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr );
bool ignorePrimePosition = false;
if( m_inTwoClickPlace )
return 0;
@@ -1044,10 +1049,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
setCursor();
// Prime the pump if the tool isn't being re-activated
if( aEvent.HasPosition() || ( !aEvent.IsReactivate()
&& ( isText || isGlobalLabel || isHierLabel || isNetLabel ) ) )
if( aEvent.HasPosition() )
{
m_toolMgr->RunAction( ACTIONS::cursorClick );
m_toolMgr->PrimeTool( aEvent.Position() );
}
else if( !aEvent.IsReactivate() && ( isText
|| isGlobalLabel
|| isHierLabel
|| isNetLabel ) )
{
m_toolMgr->PrimeTool( { 0, 0 } );
ignorePrimePosition = true;
}
// Main loop: keep receiving events
@@ -1063,6 +1075,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( item )
{
cleanup();
@@ -1164,11 +1178,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
}
// Restore cursor after dialog
controls->WarpCursor( controls->GetCursorPosition(), true );
// If we started with a click on a tool button or menu then continue with the
// current mouse position. Otherwise warp back to the original click position.
if( evt->IsPrime() && ignorePrimePosition )
cursorPos = grid.Align( controls->GetMousePosition() );
else
controls->WarpCursor( cursorPos, true );
if( item )
{
item->SetPosition( (wxPoint) cursorPos );
item->SetFlags( IS_NEW | IS_MOVING );
item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
updatePreview();
@@ -1290,6 +1310,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( sheet )
{
cleanup();
@@ -1430,8 +1452,8 @@ void SCH_DRAWING_TOOLS::sizeSheet( SCH_SHEET* aSheet, const VECTOR2I& aPos )
wxPoint pos = aSheet->GetPosition();
wxPoint size = (wxPoint) aPos - pos;
size.x = std::max( size.x, MIN_SHEET_WIDTH );
size.y = std::max( size.y, MIN_SHEET_HEIGHT );
size.x = std::max( size.x, Mils2iu( MIN_SHEET_WIDTH ) );
size.y = std::max( size.y, Mils2iu( MIN_SHEET_HEIGHT ) );
wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
+4
View File
@@ -671,6 +671,10 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
if( selection.IsHover() )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
EE_SELECTION selectionCopy = selection;
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->TestDanglingEnds();
+6 -8
View File
@@ -129,7 +129,8 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent )
undoCmd.PushItem( wrapper );
m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS, false );
DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_EESCHEMA_MILS,
MAX_PAGE_SIZE_EESCHEMA_MILS ) );
dlg.SetWksFileName( BASE_SCREEN::m_DrawingSheetFileName );
if( dlg.ShowModal() )
@@ -1534,19 +1535,16 @@ void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aP
}
if( aForceKeepAnnotations && !reference.IsEmpty() )
{
aSymbol->SetRef( &aPastePath, reference );
aSymbol->SetValue( &aPastePath, value );
aSymbol->SetFootprint( &aPastePath, footprint );
}
else
{
aSymbol->ClearAnnotation( &aPastePath );
}
// We might clear annotations but always leave the original unit number from the paste
// We might clear annotations but always leave the original unit number, value and footprint
// from the paste
aSymbol->SetUnitSelection( &aPastePath, unit );
aSymbol->SetUnit( unit );
aSymbol->SetValue( &aPastePath, value );
aSymbol->SetFootprint( &aPastePath, footprint );
}
+14 -1
View File
@@ -164,7 +164,8 @@ private:
SCH_LINE_WIRE_BUS_TOOL::SCH_LINE_WIRE_BUS_TOOL() :
EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawingLineWireBus" )
EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawingLineWireBus" ),
m_inDrawingTool( false )
{
m_busUnfold = {};
m_wires.reserve( 16 );
@@ -278,6 +279,11 @@ bool SCH_LINE_WIRE_BUS_TOOL::IsDrawingLineWireOrBus( const SELECTION& aSelection
int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
{
if( m_inDrawingTool )
return 0;
REENTRANCY_GUARD guard( &m_inDrawingTool );
DRAW_SEGMENT_EVENT_PARAMS* params = aEvent.Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
std::string tool = aEvent.GetCommandStr().get();
@@ -300,6 +306,11 @@ int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
int SCH_LINE_WIRE_BUS_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
{
if( m_inDrawingTool )
return 0;
REENTRANCY_GUARD guard( &m_inDrawingTool );
wxString* netPtr = aEvent.Parameter<wxString*>();
wxString net;
SCH_LINE* segment = nullptr;
@@ -591,6 +602,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
//
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( segment || m_busUnfold.in_progress )
{
cleanup();
+3 -4
View File
@@ -133,11 +133,10 @@ private:
void computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments, wxPoint& aPosition );
private:
/// Data related to bus unfolding tool.
BUS_UNFOLDING_T m_busUnfold;
bool m_inDrawingTool; // Reentrancy guard
/// Storage for the line segments while drawing
std::vector<SCH_LINE*> m_wires;
BUS_UNFOLDING_T m_busUnfold;
std::vector<SCH_LINE*> m_wires; // Lines being drawn
};
#endif /* SCH_LINE_WIRE_BUS_TOOL_H */
+63 -19
View File
@@ -384,6 +384,9 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
//
else if( evt->IsCancelInteractive() || evt->IsActivate() )
{
if( evt->IsCancelInteractive() )
m_frame->GetInfoBar()->Dismiss();
if( m_moveInProgress )
{
if( evt->IsActivate() )
@@ -750,8 +753,8 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
if( aItem->HasFlag( ENDPOINT ) )
line->MoveEnd( (wxPoint) aDelta );
}
break;
}
case SCH_PIN_T:
case SCH_FIELD_T:
@@ -775,13 +778,16 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
break;
}
case SCH_SHEET_PIN_T:
{
SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) aItem;
pin->SetStoredPos( pin->GetStoredPos() + (wxPoint) aDelta );
pin->ConstrainOnEdge( pin->GetStoredPos() );
break;
}
case SCH_LABEL_T:
{
SCH_TEXT* label = static_cast<SCH_TEXT*>( aItem );
@@ -799,6 +805,7 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
break;
}
default:
static_cast<SCH_ITEM*>( aItem )->Move( (wxPoint) aDelta );
break;
@@ -815,6 +822,17 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems );
bool append_undo = false;
auto doMoveItem =
[&]( EDA_ITEM* item, const VECTOR2I& delta )
{
saveCopyInUndoList( item, UNDO_REDO::CHANGED, append_undo );
append_undo = true;
moveItem( item, delta );
item->ClearFlags( IS_MOVING );
updateItem( item, true );
};
for( SCH_ITEM* it : m_frame->GetScreen()->Items() )
{
if( !it->IsSelected() )
@@ -858,12 +876,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
continue;
saveCopyInUndoList( dragItem, UNDO_REDO::CHANGED, append_undo );
append_undo = true;
moveItem( dragItem, gridpt );
dragItem->ClearFlags( IS_MOVING );
updateItem( dragItem, true );
doMoveItem( dragItem, gridpt );
}
}
}
@@ -873,13 +886,49 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
VECTOR2I gridpt = grid.AlignGrid( item->GetPosition() ) - item->GetPosition();
if( gridpt != VECTOR2I( 0, 0 ) )
{
saveCopyInUndoList( item, UNDO_REDO::CHANGED, append_undo );
append_undo = true;
doMoveItem( item, gridpt );
}
else if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
VECTOR2I topRight = sheet->GetPosition();
VECTOR2I bottomRight = topRight + sheet->GetSize();
VECTOR2I tl_gridpt = grid.AlignGrid( topRight ) - topRight;
VECTOR2I br_gridpt = grid.AlignGrid( bottomRight ) - bottomRight;
moveItem( item, gridpt );
updateItem( item, true );
item->ClearFlags( IS_MOVING );
if( tl_gridpt != VECTOR2I( 0, 0 ) || br_gridpt != VECTOR2I( 0, 0 ) )
{
doMoveItem( sheet, tl_gridpt );
VECTOR2I newSize = (VECTOR2I) sheet->GetSize() - tl_gridpt + br_gridpt;
sheet->SetSize( wxSize( newSize.x, newSize.y ) );
updateItem( sheet, true );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
VECTOR2I gridpt;
if( pin->GetSide() == SHEET_SIDE::TOP || pin->GetSide() == SHEET_SIDE::LEFT )
gridpt = tl_gridpt;
else
gridpt = br_gridpt;
if( gridpt != VECTOR2I( 0, 0 ) )
{
EDA_ITEMS drag_items;
getConnectedDragItems( pin, pin->GetConnectionPoints()[0], drag_items );
doMoveItem( pin, gridpt );
for( EDA_ITEM* dragItem : drag_items )
{
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
continue;
doMoveItem( dragItem, gridpt );
}
}
}
}
}
else
@@ -915,12 +964,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
continue;
saveCopyInUndoList( dragItem, UNDO_REDO::CHANGED, append_undo );
append_undo = true;
moveItem( dragItem, most_common );
dragItem->ClearFlags( IS_MOVING );
updateItem( dragItem, true );
doMoveItem( dragItem, most_common );
}
}
}
+6 -2
View File
@@ -256,10 +256,14 @@ int SYMBOL_EDITOR_CONTROL::DuplicateSymbol( const TOOL_EVENT& aEvent )
{
SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
LIB_ID sel = editFrame->GetTargetLibId();
// DuplicateSymbol() is called to duplicate a symbol, or to paste a previously
// saved symbol in clipboard
bool isPasteAction = aEvent.IsAction( &EE_ACTIONS::pasteSymbol );
wxString msg;
if( !sel.IsValid() )
if( !sel.IsValid() && !isPasteAction )
{
// When duplicating a symbol, a source symbol must exists.
msg.Printf( _( "No symbol selected" ) );
m_frame->ShowInfoBarError( msg );
return 0;
@@ -274,7 +278,7 @@ int SYMBOL_EDITOR_CONTROL::DuplicateSymbol( const TOOL_EVENT& aEvent )
return 0;
}
editFrame->DuplicateSymbol( aEvent.IsAction( &EE_ACTIONS::pasteSymbol ) );
editFrame->DuplicateSymbol( isPasteAction );
}
return 0;
+60 -23
View File
@@ -26,6 +26,7 @@
#include <symbol_edit_frame.h>
#include <tools/symbol_editor_drawing_tools.h>
#include <tools/symbol_editor_pin_tool.h>
#include <tools/ee_grid_helper.h>
#include <bitmaps.h>
#include <lib_text.h>
#include <dialogs/dialog_lib_text_properties.h>
@@ -67,12 +68,16 @@ bool SYMBOL_EDITOR_DRAWING_TOOLS::Init()
int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
{
KICAD_T type = aEvent.Parameter<KICAD_T>();
auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool<SYMBOL_EDITOR_PIN_TOOL>() : nullptr;
VECTOR2I cursorPos;
EDA_ITEM* item = nullptr;
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText );
KICAD_T type = aEvent.Parameter<KICAD_T>();
auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool<SYMBOL_EDITOR_PIN_TOOL>() : nullptr;
KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr );
VECTOR2I cursorPos;
bool ignorePrimePosition = false;
LIB_ITEM* item = nullptr;
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
@@ -92,20 +97,30 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
Activate();
// Must be done after Activate() so that it gets set into the correct context
getViewControls()->ShowCursor( true );
controls->ShowCursor( true );
// Set initial cursor
setCursor();
// Prime the pump
if( aEvent.HasPosition() || ( isText && !aEvent.IsReactivate() ) )
m_toolMgr->RunAction( ACTIONS::cursorClick );
if( aEvent.HasPosition() )
{
m_toolMgr->PrimeTool( aEvent.Position() );
}
else if( !aEvent.IsReactivate() && isText )
{
m_toolMgr->PrimeTool( { 0, 0 } );
ignorePrimePosition = true;
}
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
cursorPos = grid.Align( controls->GetMousePosition() );
controls->ForceCursorPosition( true, cursorPos );
auto cleanup =
[&] ()
@@ -118,6 +133,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
m_frame->GetInfoBar()->Dismiss();
if( item )
{
cleanup();
@@ -130,12 +147,26 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
else if( evt->IsActivate() )
{
if( item )
cleanup();
if( evt->IsMoveTool() )
if( item && evt->IsMoveTool() )
{
// we're already moving our own item; ignore the move tool
evt->SetPassEvent( false );
continue;
}
if( item )
{
m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel item creation." ) );
evt->SetPassEvent( false );
continue;
}
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
@@ -186,11 +217,17 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
wxFAIL_MSG( wxT( "TwoClickPlace(): unknown type" ) );
}
// Restore cursor after dialog
getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
// If we started with a click on a tool button or menu then continue with the
// current mouse position. Otherwise warp back to the original click position.
if( evt->IsPrime() && ignorePrimePosition )
cursorPos = grid.Align( controls->GetMousePosition() );
else
controls->WarpCursor( cursorPos, true );
if( item )
{
item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) );
item->SetFlags( IS_NEW | IS_MOVING );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
@@ -200,7 +237,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
setCursor();
}
getViewControls()->SetCursorPosition( cursorPos, false );
controls->SetCursorPosition( cursorPos, false );
}
// ... and second click places:
else
@@ -237,7 +274,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{
static_cast<LIB_ITEM*>( item )->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) );
item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}
@@ -247,12 +284,12 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
// Enable autopanning and cursor capture only when there is an item to be placed
getViewControls()->SetAutoPan( item != nullptr );
getViewControls()->CaptureCursor( item != nullptr );
controls->SetAutoPan( item != nullptr );
controls->CaptureCursor( item != nullptr );
}
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
controls->SetAutoPan( false );
controls->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
return 0;
}
+5 -7
View File
@@ -814,7 +814,6 @@ SHAPE_POLY_SET* APERTURE_MACRO::GetApertureMacroShape( const GERBER_DRAW_ITEM* a
const wxPoint& aShapePos )
{
SHAPE_POLY_SET holeBuffer;
bool hasHole = false;
m_shape.RemoveAllContours();
@@ -836,18 +835,17 @@ SHAPE_POLY_SET* APERTURE_MACRO::GetApertureMacroShape( const GERBER_DRAW_ITEM* a
{
m_shape.BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
holeBuffer.RemoveAllContours();
hasHole = true;
}
}
}
}
// Merge and cleanup basic shape polygons
m_shape.Simplify( SHAPE_POLY_SET::PM_FAST );
// If a hole is defined inside a polygon, we must fracture the polygon
// to be able to drawn it (i.e link holes by overlapping edges)
if( hasHole )
m_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
// A hole can be is defined inside a polygon, or the polygons themselve can create
// a hole when merged, so we must fracture the polygon to be able to drawn it
// (i.e link holes by overlapping edges)
m_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
m_boundingBox = EDA_RECT( wxPoint( 0, 0 ), wxSize( 1, 1 ) );
auto bb = m_shape.BBox();
+23 -10
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -64,16 +64,19 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
if( !openRecentGbrMenu )
{
openRecentGbrMenu = new ACTION_MENU( false, selTool );
openRecentGbrMenu->SetTitle( _( "Open Recent Gerber File" ) );
openRecentGbrMenu->SetIcon( BITMAPS::recent );
recentGbrFiles.UseMenu( openRecentGbrMenu );
recentGbrFiles.SetClearText( _( "Clear Recent Gerber Files" ) );
recentGbrFiles.UseMenu( openRecentGbrMenu );
recentGbrFiles.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentGbrMenu->SetTitle( _( "Open Recent Gerber File" ) );
recentGbrFiles.UpdateClearText( openRecentGbrMenu, _( "Clear Recent Gerber Files" ) );
fileMenu->Add( GERBVIEW_ACTIONS::openGerber );
wxMenuItem* gbrItem = fileMenu->Add( openRecentGbrMenu );
wxMenuItem* gbrItem = fileMenu->Add( openRecentGbrMenu->Clone() );
RegisterUIUpdateHandler( gbrItem->GetId(), FileHistoryCond( recentGbrFiles) );
@@ -90,8 +93,12 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
m_drillFileHistory.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentGbrMenu->SetTitle( _( "Open Recent Gerber File" ) );
m_drillFileHistory.UpdateClearText( openRecentDrlMenu, _( "Clear Recent Drill Files" ) );
fileMenu->Add( GERBVIEW_ACTIONS::openDrillFile );
wxMenuItem* drillItem = fileMenu->Add( openRecentDrlMenu );
wxMenuItem* drillItem = fileMenu->Add( openRecentDrlMenu->Clone() );
RegisterUIUpdateHandler( drillItem->GetId(), FileHistoryCond( m_drillFileHistory ) );
@@ -100,16 +107,19 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
if( !openRecentJobMenu )
{
openRecentJobMenu = new ACTION_MENU( false, selTool );
openRecentJobMenu->SetTitle( _( "Open Recent Job File" ) );
openRecentJobMenu->SetIcon( BITMAPS::recent );
m_jobFileHistory.UseMenu( openRecentJobMenu );
m_jobFileHistory.SetClearText( _( "Clear Recent Job Files" ) );
m_jobFileHistory.UseMenu( openRecentJobMenu );
m_jobFileHistory.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentJobMenu->SetTitle( _( "Open Recent Job File" ) );
m_jobFileHistory.UpdateClearText( openRecentJobMenu, _( "Clear Recent Job Files" ) );
fileMenu->Add( GERBVIEW_ACTIONS::openJobFile );
wxMenuItem* jobItem = fileMenu->Add( openRecentJobMenu );
wxMenuItem* jobItem = fileMenu->Add( openRecentJobMenu->Clone() );
RegisterUIUpdateHandler( jobItem->GetId(), FileHistoryCond( m_jobFileHistory ) );
@@ -118,7 +128,6 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
if( !openRecentZipMenu )
{
openRecentZipMenu = new ACTION_MENU( false, selTool );
openRecentZipMenu->SetTitle( _( "Open Recent Zip File" ) );
openRecentZipMenu->SetIcon( BITMAPS::recent );
m_zipFileHistory.UseMenu( openRecentZipMenu );
@@ -126,8 +135,12 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
m_zipFileHistory.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentZipMenu->SetTitle( _( "Open Recent Zip File" ) );
m_zipFileHistory.UpdateClearText( openRecentZipMenu, _( "Clear Recent Zip Files" ) );
fileMenu->Add( GERBVIEW_ACTIONS::openZipFile );
wxMenuItem* zipItem = fileMenu->Add( openRecentZipMenu );
wxMenuItem* zipItem = fileMenu->Add( openRecentZipMenu->Clone() );
RegisterUIUpdateHandler( zipItem->GetId(), FileHistoryCond( m_zipFileHistory ) );
#undef FileHistoryCond
+2 -1
View File
@@ -130,7 +130,8 @@ public:
* @param aLayer in case of items spanning multiple layers, only the shapes belonging to aLayer
* will be returned. Pass UNDEFINED_LAYER to return shapes for all layers.
*/
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const;
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
+9
View File
@@ -50,6 +50,15 @@ public:
m_init( true )
{ }
template<class T>
EDA_RECT( const BOX2<T> aBox )
{
m_pos = (wxPoint) aBox.GetPosition();
m_size.x = aBox.GetWidth();
m_size.y = aBox.GetHeight();
m_init = true;
}
virtual ~EDA_RECT() { };
wxPoint Centre() const
+11 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -104,7 +104,7 @@ public:
/**
* Add the files to the specified menu
*
* @aMenu is the menu to operate on.
* @param aMenu is the menu to operate on.
*/
void AddFilesToMenu( wxMenu* aMenu ) override;
@@ -125,6 +125,15 @@ public:
m_clearText = aClearText;
}
/**
* Update the text displayed on the menu item that clears the entire menu.
* useful after language change.
*
* @param aMenu is the menu to operate on.
* @param aClearText is the new text to use for the menu item
*/
void UpdateClearText( wxMenu* aMenu, wxString aClearText );
/**
* Clear all entries from the file history.
*/
+11
View File
@@ -146,6 +146,17 @@ enum PCB_LAYER_ID: int
#define MAX_CU_LAYERS (B_Cu - F_Cu + 1)
/**
* Enum used during connectivity building to ensure we do not query connectivity while building
* the database
*/
enum class FLASHING
{
DEFAULT, // Flashing follows connectivity
ALWAYS_FLASHED, // Always flashed for connectivity
NEVER_FLASHED, // Never flashed for connectivity
};
/// Dedicated layers for net names used in Pcbnew
enum NETNAMES_LAYER_ID: int
{
+3 -3
View File
@@ -36,9 +36,9 @@
#include <base_units.h> // for IU_PER_MILS
/// Min and max page sizes for clamping, in mils.
#define MIN_PAGE_SIZE_MILS 100
#define MAX_PAGE_SIZE_PCBNEW_MILS 48000
#define MAX_PAGE_SIZE_MILS 120000
#define MIN_PAGE_SIZE_MILS 100
#define MAX_PAGE_SIZE_PCBNEW_MILS 48000
#define MAX_PAGE_SIZE_EESCHEMA_MILS 120000
/**
+1
View File
@@ -218,6 +218,7 @@ public:
EDA_ITEM* GetItem( const KIID& aId ) const override;
void FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
void FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
// General
virtual void ReCreateOptToolbar() override { }
+6 -4
View File
@@ -117,10 +117,12 @@ public:
m_ids.push_back( dItem );
}
KIID GetMainItemID() const { return m_ids.size() > 0 ? m_ids[0] : niluuid; }
KIID GetAuxItemID() const { return m_ids.size() > 1 ? m_ids[1] : niluuid;; }
KIID GetAuxItem2ID() const { return m_ids.size() > 2 ? m_ids[2] : niluuid;; }
KIID GetAuxItem3ID() const { return m_ids.size() > 3 ? m_ids[3] : niluuid;; }
virtual KIID GetMainItemID() const { return m_ids.size() > 0 ? m_ids[0] : niluuid; }
virtual KIID GetAuxItemID() const { return m_ids.size() > 1 ? m_ids[1] : niluuid; }
virtual KIID GetAuxItem2ID() const { return m_ids.size() > 2 ? m_ids[2] : niluuid; }
virtual KIID GetAuxItem3ID() const { return m_ids.size() > 3 ? m_ids[3] : niluuid; }
std::vector<KIID> GetIDs() const { return m_ids; }
void SetParent( MARKER_BASE* aMarker ) { m_parent = aMarker; }
MARKER_BASE* GetParent() const { return m_parent; }
+3 -1
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -56,6 +56,8 @@ protected:
wxStyledTextCtrl* m_te;
wxString m_braces;
int m_lastCaretPos;
int m_lastSelStart;
int m_lastSelEnd;
bool m_suppressAutocomplete;
bool m_singleLine; // Treat <return> as OK, and skip special tab
// stop handling (including monospaced font).
+2 -1
View File
@@ -104,7 +104,8 @@ public:
* The difference between this function and wxMenu::AppendSubMenu() is the capability to
* handle icons.
*
* @param aMenu is the submenu to be added.
* @param aMenu is the submenu to be added. This should be a new instance (use Clone()) if required
* as the menu is destructed after use.
*/
wxMenuItem* Add( ACTION_MENU* aMenu );
+14
View File
@@ -204,6 +204,8 @@ public:
* @note The position may be different from the cursor position if snapping is
* enabled (@see GetCursorPosition()).
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aWorldCoordinates if true, the result is given in world coordinates, otherwise
* it is given in screen coordinates.
* @return The current mouse pointer position in either world or screen coordinates.
@@ -216,6 +218,8 @@ public:
* @note The position may be different from the mouse pointer position if snapping is
* enabled or cursor position is forced to a specific point.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @return The current cursor position in world coordinates.
*/
VECTOR2D GetCursorPosition() const
@@ -237,6 +241,8 @@ public:
* @note The position may be different from the mouse pointer position if snapping is
* enabled or cursor position is forced to a specific point.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aEnableSnapping selects whether cursor position should be snapped to the grid.
* @return The current cursor position in world coordinates.
*/
@@ -245,6 +251,8 @@ public:
/**
* Place the cursor immediately at a given point. Mouse movement is ignored.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aEnabled enable forced cursor position
* @param aPosition the position (world coordinates).
*/
@@ -260,6 +268,8 @@ public:
* The position is not forced and will be overridden with the next mouse motion event.
* Mouse cursor follows the world cursor.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aPosition is the requested cursor position in the world coordinates.
* @param aWarpView enables/disables view warp if the cursor is outside the current viewport.
*/
@@ -270,6 +280,8 @@ public:
/**
* Move the graphic crosshair cursor to the requested position expressed in world coordinates.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aPosition is the requested cursor position in the world coordinates.
* @param aWarpView enables/disables view warp if the cursor is outside the current viewport.
*/
@@ -303,6 +315,8 @@ public:
* If enabled (@see SetEnableCursorWarping(), warps the cursor to the specified position,
* expressed either in the screen coordinates or the world coordinates.
*
* @note The position is clamped if outside of coordinates representation limits.
*
* @param aPosition is the position where the cursor should be warped.
* @param aWorldCoordinates if true treats aPosition as the world coordinates, otherwise it
* uses it as the screen coordinates.
+7
View File
@@ -24,7 +24,10 @@
#ifndef KICAD_WX_GRID_H
#define KICAD_WX_GRID_H
#include <wx/event.h>
#include <wx/grid.h>
#include <wx/version.h>
class WX_GRID : public wxGrid
{
@@ -119,6 +122,10 @@ protected:
void onGridColMove( wxGridEvent& aEvent );
void onGridCellSelect( wxGridEvent& aEvent );
#if wxCHECK_VERSION( 3, 1, 0 )
void onDPIChanged(wxDPIChangedEvent& event);
#endif
bool m_weOwnTable;
};
+4 -2
View File
@@ -62,13 +62,15 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
if( !openRecentMenu )
{
openRecentMenu = new ACTION_MENU( false, controlTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( BITMAPS::recent );
fileHistory.UseMenu( openRecentMenu );
fileHistory.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentMenu->SetTitle( _( "Open Recent" ) );
fileMenu->Add( KICAD_MANAGER_ACTIONS::newProject );
fileMenu->Add( KICAD_MANAGER_ACTIONS::newFromTemplate );
@@ -79,7 +81,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
fileMenu->Add( KICAD_MANAGER_ACTIONS::openProject );
wxMenuItem* item = fileMenu->Add( openRecentMenu );
wxMenuItem* item = fileMenu->Add( openRecentMenu->Clone() );
// Add the file menu condition here since it needs the item ID for the submenu
ACTION_CONDITIONS cond;
@@ -133,6 +133,47 @@ VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec, bool only45 = false )
}
/**
* Clamps a vector to values that can be negated, respecting numeric limits
* of coordinates data type with specified padding.
*
* Numeric limits are (-2^31 + 1) to (2^31 - 1).
*
* Takes care of rounding in case of floating point to integer conversion.
*
* @param aCoord - vector to clamp.
* @param aPadding - padding from the limits. Must not be negative.
* @return clamped vector.
*/
template <typename in_type, typename ret_type = in_type, typename pad_type = unsigned int,
typename = typename std::enable_if<std::is_unsigned<pad_type>::value>::type>
VECTOR2<ret_type> GetClampedCoords( const VECTOR2<in_type>& aCoords, pad_type aPadding = 0u )
{
typedef std::numeric_limits<int> coord_limits;
long max = coord_limits::max() - aPadding;
long min = -max;
in_type x = aCoords.x;
in_type y = aCoords.y;
if( x < min )
x = min;
else if( x > max )
x = max;
if( y < min )
y = min;
else if( y > max )
y = max;
if( !std::is_integral<in_type>() && std::is_integral<ret_type>() )
return VECTOR2<ret_type>( KiROUND( x ), KiROUND( y ) );
return VECTOR2<ret_type>( x, y );
}
/**
* Test if any part of a line falls within the bounds of a rectangle.
*
@@ -420,7 +420,7 @@ void TransformTrapezoidToPolygon( SHAPE_POLY_SET& aCornerBuffer, const wxPoint&
corners.push_back( ROUNDED_CORNER( size.x + aDeltaY, size.y - aDeltaX ) );
corners.push_back( ROUNDED_CORNER( -size.x - aDeltaY, size.y + aDeltaX ) );
if( aDeltaY == size.x || aDeltaX == size.y )
if( std::abs( aDeltaY ) == std::abs( size.x ) || std::abs( aDeltaX ) == std::abs( size.y ) )
CornerListRemoveDuplicates( corners );
}
@@ -536,6 +536,17 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const wxPoint& aStart
const wxPoint& aMid, const wxPoint& aEnd, int aWidth,
int aError, ERROR_LOC aErrorLoc )
{
SEG startToEnd( aStart, aEnd );
int distanceToMid = startToEnd.Distance( aMid );
if( distanceToMid <= 1 )
{
// Not an arc but essentially a straight line with a small error
TransformOvalToPolygon( aCornerBuffer, aStart, aEnd, aWidth + distanceToMid, aError,
aErrorLoc );
return;
}
SHAPE_ARC arc( aStart, aMid, aEnd, aWidth );
// Currentlye have currently 2 algos:
// the first approximates the thick arc from its outlines
+1 -1
View File
@@ -1518,7 +1518,7 @@ bool SHAPE_POLY_SET::Collide( const SHAPE* aShape, int aClearance, int* aActual,
return false;
}
const_cast<SHAPE_POLY_SET*>( this )->CacheTriangulation( true );
const_cast<SHAPE_POLY_SET*>( this )->CacheTriangulation( false );
int actual = INT_MAX;
VECTOR2I location;
+5 -2
View File
@@ -54,13 +54,16 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
if( !openRecentMenu )
{
openRecentMenu = new ACTION_MENU( false, selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( BITMAPS::recent );
recentFiles.UseMenu( openRecentMenu );
recentFiles.AddFilesToMenu();
}
// Ensure the title is up to date after changing language
openRecentMenu->SetTitle( _( "Open Recent" ) );
recentFiles.UpdateClearText( openRecentMenu, _( "Clear Recent Files" ) );
//-- File menu -------------------------------------------------------
//
ACTION_MENU* fileMenu = new ACTION_MENU( false, selTool );
@@ -68,7 +71,7 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
fileMenu->Add( ACTIONS::doNew );
fileMenu->Add( ACTIONS::open );
wxMenuItem* item = fileMenu->Add( openRecentMenu );
wxMenuItem* item = fileMenu->Add( openRecentMenu->Clone() );
// Add the file menu condition here since it needs the item ID for the submenu
ACTION_CONDITIONS cond;
+3
View File
@@ -204,6 +204,9 @@ int PL_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
//
else if( evt->IsCancelInteractive() || evt->IsActivate() )
{
if( evt->IsCancelInteractive() )
m_frame->GetInfoBar()->Dismiss();
if( m_moveInProgress )
{
if( evt->IsActivate() )
@@ -89,7 +89,9 @@ int PL_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent )
{
m_frame->SaveCopyInUndoList();
DIALOG_PAGES_SETTINGS dlg( m_frame, IU_PER_MILS, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
DIALOG_PAGES_SETTINGS dlg( m_frame, IU_PER_MILS,
wxSize( MAX_PAGE_SIZE_EESCHEMA_MILS,
MAX_PAGE_SIZE_EESCHEMA_MILS ) );
dlg.SetWksFileName( m_frame->GetCurrentFileName() );
dlg.EnableWksFileNamePicker( false );
+1 -1
View File
@@ -178,7 +178,7 @@ bool BOARD_ITEM::ptr_cmp::operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b
}
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::shared_ptr<SHAPE> shape;
+27 -1
View File
@@ -798,7 +798,33 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate )
for( PCB_LAYER_ID layer : commonLayers.Seq() )
{
if( parentA->GetEffectiveShape( layer )->Collide( parentB->GetEffectiveShape( layer ).get() ) )
FLASHING flashingA = FLASHING::NEVER_FLASHED;
FLASHING flashingB = FLASHING::NEVER_FLASHED;
if( const PAD* pad = dyn_cast<const PAD*>( parentA ) )
{
if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
flashingA = FLASHING::ALWAYS_FLASHED;
}
else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentA ) )
{
if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
flashingA = FLASHING::ALWAYS_FLASHED;
}
if( const PAD* pad = dyn_cast<const PAD*>( parentB ) )
{
if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
flashingB = FLASHING::ALWAYS_FLASHED;
}
else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentB ) )
{
if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
flashingB = FLASHING::ALWAYS_FLASHED;
}
if( parentA->GetEffectiveShape( layer, flashingA )->Collide(
parentB->GetEffectiveShape( layer, flashingB ).get() ) )
{
m_item->Connect( aCandidate );
aCandidate->Connect( m_item );
+14 -25
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Brian Piccioni <brian@documenteddesigns.com>
*
* This program is free software; you can redistribute it and/or
@@ -30,14 +30,10 @@
#include <confirm.h>
#include <ctype.h>
#include <dialog_board_reannotate.h>
#include <fstream>
#include <string_utils.h> // StrNumCmp
#include <kiface_base.h>
#include <mail_type.h>
#include <pcbnew_settings.h>
#include <refdes_utils.h>
#include <sstream>
#include <tool/tool_manager.h>
#include <tool/grid_menu.h>
#include <wx/valtext.h>
@@ -136,16 +132,12 @@ DIALOG_BOARD_REANNOTATE::DIALOG_BOARD_REANNOTATE( PCB_EDIT_FRAME* aParentFrame )
m_selection = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
if( !m_selection.Empty() )
m_annotationChoice = AnnotationChoice::AnnotateSelected;
m_annotationScope = AnnotateSelected;
for( wxRadioButton* button : AnnotateWhat )
for( wxRadioButton* button : m_scopeRadioButtons )
button->SetValue( false );
m_annotationChoice = ( m_sortCode >= (int) AnnotateWhat.size() ) ?
AnnotationChoice::AnnotateAll :
m_annotationChoice;
AnnotateWhat[m_annotationChoice]->SetValue( true );
m_scopeRadioButtons[m_annotationScope]->SetValue( true );
reannotate_down_right_bitmap->SetBitmap( KiBitmap( BITMAPS::reannotate_right_down ) );
reannotate_right_down_bitmap->SetBitmap( KiBitmap( BITMAPS::reannotate_left_down ) );
@@ -176,7 +168,7 @@ DIALOG_BOARD_REANNOTATE::~DIALOG_BOARD_REANNOTATE()
cfg->m_Reannotate.grid_index = m_gridIndex;
cfg->m_Reannotate.sort_code = m_sortCode;
cfg->m_Reannotate.annotation_choice = m_annotationChoice;
cfg->m_Reannotate.annotation_choice = m_annotationScope;
cfg->m_Reannotate.report_severity = m_severity;
cfg->m_Reannotate.front_refdes_start = m_FrontRefDesStart->GetValue();
@@ -198,7 +190,7 @@ void DIALOG_BOARD_REANNOTATE::InitValues( void )
m_gridIndex = cfg->m_Reannotate.grid_index ;
m_sortCode = cfg->m_Reannotate.sort_code ;
m_annotationChoice = cfg->m_Reannotate.annotation_choice ;
m_annotationScope = cfg->m_Reannotate.annotation_choice ;
m_severity = cfg->m_Reannotate.report_severity;
m_FrontRefDesStart->SetValue( cfg->m_Reannotate.front_refdes_start );
@@ -311,7 +303,7 @@ void DIALOG_BOARD_REANNOTATE::MakeSampleText( wxString& aMessage )
wxString tmp;
aMessage.Printf( _( "\n%s footprints will be reannotated." ),
_( AnnotateString[m_annotationChoice] ) );
_( AnnotateString[m_annotationScope] ) );
if( !m_ExcludeList->GetValue().empty() )
{
@@ -418,18 +410,16 @@ void DIALOG_BOARD_REANNOTATE::GetParameters()
m_sortGridy = m_sortGridx;
}
int i = 0;
m_annotationScope = AnnotateAll;
for( wxRadioButton* button : AnnotateWhat )
for( wxRadioButton* button : m_scopeRadioButtons )
{
if( button->GetValue() )
break;
else
i++;
m_annotationScope++;
}
m_annotationChoice = ( i >= (int) AnnotateWhat.size() ) ? AnnotationChoice::AnnotateAll : i;
m_MessageWindow->SetLazyUpdate( true );
}
@@ -642,7 +632,7 @@ bool DIALOG_BOARD_REANNOTATE::ReannotateBoard()
bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes )
{
bool annotateSelected;
bool annotateSelected = m_AnnotateSelection->GetValue();
bool annotateFront = m_AnnotateFront->GetValue(); // Unless only doing back
bool annotateBack = m_AnnotateBack->GetValue(); // Unless only doing front
bool skipLocked = m_ExcludeLocked->GetValue();
@@ -657,7 +647,7 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
std::vector<KIID> selected;
if( m_AnnotateSelection->GetValue() )
if( annotateSelected )
{
for( EDA_ITEM* item : m_selection )
{
@@ -667,8 +657,6 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
}
}
annotateSelected = !selected.empty();
wxString exclude;
// Break exclude list into words.
@@ -799,7 +787,8 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<RefDesInfo>& aBadR
{
if( m_changeArray[i].NewRefDes == m_changeArray[j].NewRefDes )
{
ShowReport( wxString::Format( _( "Duplicate instances of %s" ), m_changeArray[j].NewRefDes ),
ShowReport( wxString::Format( _( "Duplicate instances of %s" ),
m_changeArray[j].NewRefDes ),
RPT_SEVERITY_ERROR );
if( errorcount++ > MAXERROR )
+8 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Brian Piccioni <brian@documenteddesigns.com>
*
* This program is free software; you can redistribute it and/or
@@ -23,8 +23,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DIALOG_BOARD_REANNOTATE_H_
#define DIALOG_BOARD_REANNOTATE_H_
#ifndef DIALOG_BOARD_REANNOTATE_H
#define DIALOG_BOARD_REANNOTATE_H
#include <board.h>
#include <footprint.h>
@@ -60,9 +60,9 @@ enum ActionCode
Exclude
};
enum AnnotationChoice
enum AnnotationScope
{
AnnotateAll,
AnnotateAll = 0,
AnnotateFront,
AnnotateBack,
AnnotateSelected
@@ -115,7 +115,7 @@ private:
m_Left_Up
};
std::vector<wxRadioButton*> AnnotateWhat = {
std::vector<wxRadioButton*> m_scopeRadioButtons = {
m_AnnotateAll,
m_AnnotateFront,
m_AnnotateBack,
@@ -200,7 +200,7 @@ private:
int m_sortCode;
int m_gridIndex;
int m_annotationChoice;
int m_annotationScope;
int m_severity;
double m_sortGridx;
@@ -215,4 +215,4 @@ private:
APP_SETTINGS_BASE* m_Config;
};
#endif /* DIALOG_BOARD_REANNOTATECLASSES_H_ */
#endif /* DIALOG_BOARD_REANNOTATE_H */
+25 -1
View File
@@ -396,7 +396,31 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
if( board->GetVisibleLayers().test( principalLayer ) )
m_frame->SetActiveLayer( principalLayer );
if( m_centerMarkerOnIdle )
if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
{
PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
if( track )
{
int net = track->GetNetCode();
std::vector<BOARD_ITEM*> segs;
for( const KIID& id : rc_item->GetIDs() )
{
PCB_TRACK* candidate = dynamic_cast<PCB_TRACK*>( board->GetItem( id ) );
if( candidate && candidate->GetNetCode() == net )
segs.push_back( candidate );
}
m_frame->FocusOnItems( segs, principalLayer );
}
else
{
m_frame->FocusOnItem( item, principalLayer );
}
}
else if( m_centerMarkerOnIdle )
{
// we already came from a cross-probe of the marker in the document; don't go
// around in circles
+2 -1
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -160,6 +160,7 @@ void DIALOG_FOOTPRINT_CHECKER::runChecks()
void DIALOG_FOOTPRINT_CHECKER::SetMarkersProvider( RC_ITEMS_PROVIDER* aProvider )
{
m_markersProvider = aProvider;
m_markersTreeModel->SetProvider( aProvider );
updateDisplayedCounts();
}
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -267,9 +267,12 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
return false;
LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();
if( !m_item )
return true;
int layer = m_LayerSelectionCtrl->GetLayerSelection();
BOARD_COMMIT commit( m_parent );
commit.Modify( m_item );
if( m_flipStartEnd && m_item->GetShape() != SHAPE_T::ARC )
@@ -311,16 +314,17 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
m_item->SetCenter( wxPoint( KiROUND( center.x ), KiROUND( center.y ) ) );
}
if( m_fp_item )
{
// We are editing a footprint; init the item coordinates relative to the footprint anchor.
m_fp_item->SetStart0( m_fp_item->GetStart() );
m_fp_item->SetEnd0( m_fp_item->GetEnd() );
if( m_item->GetShape() == SHAPE_T::ARC )
if( m_fp_item->GetShape() == SHAPE_T::ARC )
m_fp_item->SetCenter0( m_fp_item->GetCenter() );
if( m_item->GetShape() == SHAPE_T::BEZIER )
if( m_fp_item->GetShape() == SHAPE_T::BEZIER )
{
m_fp_item->SetBezierC1_0( m_fp_item->GetBezierC1() );
m_fp_item->SetBezierC2_0( m_fp_item->GetBezierC2() );
+4 -4
View File
@@ -1749,25 +1749,25 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
else
delta.y = m_trapDelta.GetValue();
if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
if( delta.x < 0 && delta.x < -aPad->GetSize().y )
{
delta.x = -aPad->GetSize().y + 2;
error = true;
}
if( delta.x > 0 && delta.x >= aPad->GetSize().y )
if( delta.x > 0 && delta.x > aPad->GetSize().y )
{
delta.x = aPad->GetSize().y - 2;
error = true;
}
if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
if( delta.y < 0 && delta.y < -aPad->GetSize().x )
{
delta.y = -aPad->GetSize().x + 2;
error = true;
}
if( delta.y > 0 && delta.y >= aPad->GetSize().x )
if( delta.y > 0 && delta.y > aPad->GetSize().x )
{
delta.y = aPad->GetSize().x - 2;
error = true;
+2 -2
View File
@@ -814,8 +814,8 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
};
wxString path = m_plotOpts.GetOutputDirectory();
path = ExpandTextVars( path, &textResolver, nullptr, nullptr );
path = ExpandEnvVarSubstitutions( path, nullptr );
path = ExpandTextVars( path, &textResolver, nullptr, board->GetProject() );
path = ExpandEnvVarSubstitutions( path, board->GetProject() );
wxFileName outputDir = wxFileName::DirName( path );
wxString boardFilename = m_parent->GetBoard()->GetFileName();
+6 -2
View File
@@ -76,8 +76,12 @@ void DIALOG_PNS_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
m_settings.SetOptimizeEntireDraggedTrack( m_optimizeEntireDraggedTrack->GetValue() );
m_settings.SetAutoPosture( m_autoPosture->GetValue() );
m_settings.SetFixAllSegments( m_fixAllSegments->GetValue() );
m_settings.SetAllowDRCViolations( m_violateDrc->GetValue() );
m_settings.SetFreeAngleMode( m_freeAngleMode->GetValue() );
if( m_violateDrc->IsEnabled() )
m_settings.SetAllowDRCViolations( m_violateDrc->GetValue() );
if( m_freeAngleMode->IsEnabled() )
m_settings.SetFreeAngleMode( m_freeAngleMode->GetValue() );
aEvent.Skip(); // ends returning wxID_OK (default behavior)
}
+3 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1055,7 +1055,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
EscapeHTML( c->condition->GetExpression() ) ) )
}
if( c->condition->EvaluateFor( a, b, aLayer, aReporter ) )
if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
{
REPORT( implicit ? _( "Constraint applied." )
: _( "Rule applied; overrides previous constraints." ) )
@@ -1133,6 +1133,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
if( localA > global || localB > global )
{
constraint.SetParentRule( nullptr );
constraint.SetName( m_msg );
constraint.m_Value.SetMin( clearance );
return constraint;
+26 -2
View File
@@ -309,7 +309,7 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
case DRCE_FOOTPRINT_TYPE_MISMATCH: return std::make_shared<DRC_ITEM>( footprintTypeMismatch );
case DRCE_PAD_TH_WITH_NO_HOLE: return std::make_shared<DRC_ITEM>( footprintTHPadhasNoHole );
default:
wxFAIL_MSG( "Unknown DRC error code" );
wxFAIL_MSG( wxT( "Unknown DRC error code" ) );
return nullptr;
}
}
@@ -328,11 +328,35 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( const wxString& aErrorKey )
}
KIID DRC_ITEM::GetAuxItem2ID() const
{
if( m_errorCode == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
{
// we have lots of segments, but it's enough to show the first P and the first N
return niluuid;
}
return m_ids.size() > 2 ? m_ids[2] : niluuid;
}
KIID DRC_ITEM::GetAuxItem3ID() const
{
if( m_errorCode == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
{
// we have lots of segments, but it's enough to show the first P and the first N
return niluuid;
}
return m_ids.size() > 3 ? m_ids[3] : niluuid;
}
wxString DRC_ITEM::GetViolatingRuleDesc() const
{
if( m_violatingRule )
return wxString::Format( _( "Rule: %s" ), m_violatingRule->m_Name );
else
return _("Local override" );
return _( "Local override" );
}
+3
View File
@@ -115,6 +115,9 @@ public:
void SetViolatingTest( DRC_TEST_PROVIDER *aProvider ) { m_violatingTest = aProvider; }
DRC_TEST_PROVIDER* GetViolatingTest() const { return m_violatingTest; }
KIID GetAuxItem2ID() const override;
KIID GetAuxItem3ID() const override;
private:
DRC_ITEM( int aErrorCode = 0, const wxString& aTitle = "", const wxString& aSettingsKey = "" )
{
+31 -2
View File
@@ -310,11 +310,37 @@ public:
*/
bool QueryColliding( EDA_RECT aBox, SHAPE* aRefShape, PCB_LAYER_ID aLayer ) const
{
SHAPE_POLY_SET* poly = dynamic_cast<SHAPE_POLY_SET*>( aRefShape );
int min[2] = { aBox.GetX(), aBox.GetY() };
int max[2] = { aBox.GetRight(), aBox.GetBottom() };
bool collision = false;
auto visit =
// Special case the polygon case. Otherwise we'll call its Collide() method which will
// triangulate it as well and then do triangle/triangle collisions. This ends up being
// slower than 4 calls to PointInside().
auto polyVisitor =
[&]( ITEM_WITH_SHAPE* aItem ) -> bool
{
SHAPE* shape = aItem->shape;
wxASSERT( dynamic_cast<SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape ) );
auto tri = static_cast<SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape );
const SHAPE_LINE_CHAIN& outline = poly->Outline( 0 );
if( outline.PointInside( tri->GetPoint( 0 ) )
|| outline.PointInside( tri->GetPoint( 1 ) )
|| outline.PointInside( tri->GetPoint( 2 ) )
|| tri->PointInside( outline.CPoint( 0 ) ) )
{
collision = true;
return false;
}
return true;
};
auto visitor =
[&]( ITEM_WITH_SHAPE* aItem ) -> bool
{
if( aRefShape->Collide( aItem->shape, 0 ) )
@@ -326,7 +352,10 @@ public:
return true;
};
this->m_tree[aLayer]->Search( min, max, visit );
if( poly && poly->OutlineCount() == 1 )
this->m_tree[aLayer]->Search( min, max, polyVisitor );
else
this->m_tree[aLayer]->Search( min, max, visitor );
return collision;
}
+4 -4
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -41,7 +41,7 @@ DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
PCB_LAYER_ID aLayer, REPORTER* aReporter )
int aConstraint, PCB_LAYER_ID aLayer, REPORTER* aReporter )
{
if( GetExpression().IsEmpty() )
return true;
@@ -54,7 +54,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
return false;
}
PCB_EXPR_CONTEXT ctx( aLayer );
PCB_EXPR_CONTEXT ctx( aConstraint, aLayer );
if( aReporter )
{
@@ -109,7 +109,7 @@ bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSou
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
PCB_EXPR_CONTEXT preflightContext( F_Cu );
PCB_EXPR_CONTEXT preflightContext( 0, F_Cu );
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
return ok;
+3 -3
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -38,8 +38,8 @@ public:
DRC_RULE_CONDITION( const wxString& aExpression = "" );
~DRC_RULE_CONDITION();
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer,
REPORTER* aReporter = nullptr );
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, int aConstraint,
PCB_LAYER_ID aLayer, REPORTER* aReporter = nullptr );
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
+14 -12
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -154,7 +154,7 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporte
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
"'rule', 'version'" );
wxT( "rule or version" ) );
reportError( msg );
parseUnknown();
}
@@ -231,7 +231,7 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
"constraint, condition or disallow" );
wxT( "constraint, condition, or disallow" ) );
reportError( msg );
parseUnknown();
}
@@ -255,9 +255,10 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
if( (int) token == DSN_RIGHT || token == T_EOF )
{
msg.Printf( _( "Missing constraint type.| Expected %s." ),
"clearance, hole_clearance, edge_clearance, hole, hole_to_hole, "
"courtyard_clearance, silk_clearance, track_width, annular_width, via_diameter, "
"disallow, length, skew, via_count, diff_pair_gap or diff_pair_uncoupled" );
wxT( "clearance, hole_clearance, edge_clearance, hole, hole_to_hole, "
"courtyard_clearance, silk_clearance, track_width, annular_width, "
"via_diameter, disallow, length, skew, via_count, diff_pair_gap, or "
"diff_pair_uncoupled" ) );
reportError( msg );
return;
}
@@ -283,9 +284,10 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
case T_diff_pair_uncoupled: c.m_Type = DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
"clearance, hole_clearance, edge_clearance, hole_size, hole_to_hole, "
"courtyard_clearance, silk_clearance, track_width, annular_width, via_diameter, "
"disallow, length, skew, diff_pair_gap or diff_pair_uncoupled." );
wxT( "clearance, hole_clearance, edge_clearance, hole_size, hole_to_hole, "
"courtyard_clearance, silk_clearance, track_width, annular_width, "
"via_diameter, disallow, length, skew, diff_pair_gap, or "
"diff_pair_uncoupled" ) );
reportError( msg );
}
@@ -321,8 +323,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
"track, via, micro_via, buried_via, pad, zone, text, graphic, hole "
"or footprint." );
wxT( "track, via, micro_via, buried_via, pad, zone, text, graphic, "
"hole, or footprint." ) );
reportError( msg );
break;
}
@@ -411,7 +413,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"min, max or opt" );
wxT( "min, max, or opt" ) );
reportError( msg );
parseUnknown();
}

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