2218 Commits

Author SHA1 Message Date
Jon Evans eec5b07179 Add 10.99 qa config dir 2026-03-19 22:05:21 -04:00
Damjan Prerad 77140167a6 QA: fix single-member group save 2026-03-19 17:38:48 +01:00
Seth Hillbrand 36f0da1556 eeschema: abort async loads before destroying library tables
Background async library loading workers hold raw LIBRARY_TABLE_ROW
pointers into the LIBRARY_TABLE::m_rows vector. When ProjectChanged()
calls LoadProjectTables(), it destroys the old LIBRARY_TABLE objects
via unique_ptr replacement.

The workers were not aborted until after the tables were destroyed,
creating a window where workers could access freed memory.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23480
2026-03-18 12:18:23 -07:00
Seth Hillbrand 5d0485c85f qa: fix remote provider test failures 2026-03-18 08:00:12 -07:00
Seth Hillbrand 216ad00bea Fix test_remote_provider_metadata schema path for PPA builds
The schemaPath() helper used __FILE__ to navigate from the test source
file up to the repository root, then down to resources/schemas/. This
breaks when dpkg-buildflags injects -ffile-prefix-map which remaps the
absolute source path to a relative one.  The Normalize() call then
resolves the relative path against the test working directory (inside
the build tree), producing a bogus path that cannot reach the source
tree's schema files.

Replace the __FILE__ navigation with QA_SRC_ROOT compile definition
2026-03-16 16:42:22 -07:00
Seth Hillbrand 902048a172 Move history autosave Prettify, file I/O, and git ops to background thread
Savers now serialize to in-memory HISTORY_FILE_DATA on the UI thread,
then Prettify + file writes + git stage/diff/commit run on a background
thread via GetKiCadThreadPool(). An atomic skip-if-busy flag prevents
overlapping saves; WaitForPendingSave() ensures clean shutdown.

Extracted FormatBoardToFormatter and FormatSchematicToFormatter so
SaveToHistory can serialize without touching disk. PROJECT savers use
sourcePath for file-copy semantics since project files are small.
2026-03-16 12:16:45 -07:00
John Beard 8da9149da2 Allegro: adjust sometimes-untrue test for FP consistency
The old FP backside logic was to flip anything on the back layer.
However this doesn't work for FPs with things on both sides, which
are rare but do exist (BB-AI-64 power socket for example has silk
on both sides).

In particular, there are some parts that have courtyards on the bottom
for top-side SMD fps:

 - MainBoard - the U1 courtyard is on the back - A mistake I think,
   but the layer class is indeed 0x09/0xfa - PLACE_BOUND_BOTTOM.
 - VCU118 - U1 has front and back courtyards too.
 - BeagleBone Black has a back CY for a thernal pad

So this test is not universally true. Restrict to a board (EVK
BaseBoard) that hs back SMD parts, but no violations of the
principle.
2026-03-15 01:50:07 +08:00
John Beard 874215e5af Allegro: fix versioned field in 0x22 blocks.
0x22 is a rare field wedon't see much. BB-AI is a V172 file, but
the 0x22 field has this element, so it must be at least V172, not
V174.

Add a block test to really nail this down (at least for V172!)

This allows BB-AI-64 to load successfully.
2026-03-14 14:48:35 +08:00
Seth Hillbrand 305301600b Fix broken group membership when saving design blocks
saveSelectionToDesignBlock() used Clone() for groups, which creates a
shallow copy where m_items still references original board items. The
code then separately cloned children via RunOnChildren(cloneAndAdd) on
the original group, but never updated the cloned group's m_items to
reference the new clones. This resulted in design blocks with groups
whose member UUIDs referenced nonexistent items. On reload, the group
would have no children.

Additionally, addNetIfNeeded was called on the original group's children
rather than the clones, corrupting net assignments on the real board.

Replace the shallow Clone()+manual child cloning with DeepClone(), which
recursively clones all children with correct group ownership. The deep
clone and its children are then added to the temporary board for
serialization.

Related https://gitlab.com/kicad/code/kicad/-/issues/23356
2026-03-13 14:27:44 -07:00
Seth Hillbrand 57ea841427 Don't re-prune min-width for same-net zone knockouts
The postKnockoutMinWidthPrune() deflate/inflate cycle needs the
same-net zone apron protection as the initial min-width pass.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23418
2026-03-13 12:44:14 -07:00
Seth Hillbrand eeb640a4da Fix Windows MSVC link error in qa_common test executable.
Replace direct nlohmann/json.hpp includes with json_common.h in the
remote provider test files
2026-03-11 13:30:57 -07:00
Seth Hillbrand 9482730559 Eeschema: share SCH_SCREEN across top-level sheets referencing same file
When multiple top-level sheets in a multi-root schematic reference the
same sub-sheet file, each sub-sheet must share a single SCH_SCREEN
object.  Previously, loadHierarchy() only searched the current root
sheet's hierarchy for an existing screen, so screens loaded by earlier
top-level sheets were never found.  This caused each top-level sheet to
create its own copy of the shared sub-sheet's screen, leading to data
loss on save as later writes would overwrite earlier ones.

Add m_loadedRootSheets to SCH_IO_KICAD_SEXPR to track root sheets from
prior LoadSchematicFile() calls within the same IO instance.  During
loadHierarchy(), after the existing search fails, also search through
previously loaded root sheets.  The cache is cleared when the SCHEMATIC
pointer changes, preventing stale references when the IO object is
reused for unrelated loads.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23403
2026-03-11 11:23:02 -07:00
Seth Hillbrand 2dbba4a60a Remote Symbol: consolidate, update and harden
Extract duplicated helpers from remote provider files into shared
utilities.  Split sendRpcMessage into purpose-specific functions.
Implement standard nonce-based exchange for re-auth.  Provide
additional models for more efficient model/symbol/fp/etc using
external URLs.  This allows us to better handle connection errors,
retries and large data packets.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23381
2026-03-11 06:41:44 -07:00
Seth Hillbrand 42928c8b2f Fix Move command grabbing from grid point instead of anchor
The Move command grabbed footprints from the nearest grid point rather
than the footprint anchor. This was caused by the reference point being
grid-aligned at drag start (commit 89be3fd390), which was a workaround
for fractional-nanometer positioning errors with non-page display origin.

Fix the root cause instead: AlignGrid(VECTOR2I, VECTOR2D, VECTOR2D)
relied on implicit VECTOR2D->VECTOR2I truncation to pass grid parameters
to computeNearest. For grid sizes that aren't exact in IEEE 754 double
(e.g., 0.254mm = 10 mil becomes 253999.999... instead of 254000), the
truncation produces incorrect grid sizes. Use KiROUND for the conversion
so all grid operations produce exact grid multiples.

With AlignGrid returning correct positions, the move tool no longer needs
to grid-align its reference point. Restore the anchor-based grab and the
GetMoveWarpsCursor() preference that 89be3fd390 removed.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23308
2026-03-10 11:07:39 -07:00
John Beard 53c2094764 QA Pcbnew: add auto plugin mode to pcbnew tools
This means it can read all supported file types from the command line as
filename. Stream input (for fuzzing) still requires the plugin to be
specified and for the plugin to support a stream interface.

This is useful for putting profilers onto importers without confusing it
with GUI init, libraries, etc.
2026-03-10 22:32:20 +08:00
Seth Hillbrand e47e3cc166 Fix creepage DRC skipping slot edges with multiple Edge.Cuts rectangles
When generating paths between board edge nodes from different Edge.Cuts
shapes (e.g., corners of two rectangular slots), both parents were added
to the IgnoreForTest list.

For POINT shapes (rectangle/polygon corners), the segments_intersect
function already excludes shared-endpoint intersections, so skipping
the parent shape is unnecessary. Only circle board edge shapes need
their parent in IgnoreForTest because segmentIntersectsCircle has no
endpoint exclusion.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23364
2026-03-09 16:21:05 -07:00
Seth Hillbrand 7c4229c066 Re-prune minimum-width violations after zone knockouts
Zone-to-zone clearance knockouts and higher-priority zone subtraction
happen after the initial deflate/inflate minimum-width enforcement
cycle.  These knockouts can carve out material and leave thin copper
strips that violate the zone's minimum width constraint.

Add a second deflate/inflate pass that runs only when knockouts were
actually applied.  The result is intersected with the pre-deflate
boundary to prevent re-inflation into cleared areas (keepouts, pad
clearances, etc.).

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23332
2026-03-09 12:40:37 -07:00
Damjan Prerad 0baff2c0b2 DRC: Default track-not-centered-on-via to warning, fix tests 2026-03-08 18:20:00 +01:00
John Beard d5e129a3a0 Pcbnew/Allegro: Break out zone merge function.
This is a tricky function that really needs a test around it.

Also it has several assumptions and traps:

 - It will not work if the zones have multiple polygons in the poly sets
 - It will not work if any polygon has line chains in a different order
 - It is quadratic in number of zones and the compare itself is
   superlinear (Simplify is called, evilly in a const function, which is
   quadratic) and in a cyclic comparison, sort, which is presumably nlog-n
   ish.

However, at least for the quadratic nature, profiling shows this to be
absolutely insignificant even for the VCU118 board.
2026-03-08 22:17:43 +08:00
Jon Evans c62b9aad23 API: Avoid redundant serialization of polyline arcs
Fixes https://gitlab.com/kicad/code/kicad-python/-/issues/79

(cherry picked from commit 0aeb33f94f)
2026-03-08 00:22:23 -05:00
John Beard f8c62b3b36 QA: Standardise on the modern Boost test printer style
boost_test_print_type was introduced in 1.64 and we can tidy
up/standardise the old style printers in boost::test_tools::tt_detail
and "normal" stream operators which risk conflicts if one appears in
a header in future.
2026-03-08 01:45:27 +08:00
John Beard c8b2bef4f5 Pcbnew: preserve courtyard cache on Flip and Rotate
This isn't a major hotspot, but Flip does show up a little on
a profile of board loading, so it not nothing, and it's quite
easy to maintain the existing geometry here.

Also maintains the hull on rotation.

And add some tests around the courtyard and hull class invariants.
2026-03-08 00:53:34 +08:00
Seth Hillbrand 2dbaa8d025 Initialize variant attributes from symbol/sheet defaults during parse
The S-expression serializer only writes variant attributes that differ
from the symbol/sheet default values.  When deserializing, the parser
created variants with all-false attribute defaults from the VARIANT
constructor.  This meant any variant attribute matching the owner's
default was silently lost on save/reload.

Call InitializeAttributes() on each variant immediately after
construction in the parser so that unparsed attributes inherit the
correct default values from the owning symbol or sheet.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23347
2026-03-06 12:31:34 -08:00
Seth Hillbrand dd22dbbc43 Allow negative silk screen clearance values to be saved
The PARAM_SCALED lower bound for min_silk_clearance was 0.0mm, which
caused negative values to be reset to the default on project reload.
Users set negative silk clearance to suppress DRC violations for
footprints that intentionally overlap their silkscreen.

Changed the lower bound from 0.0mm to -10.0mm so negative values
survive the JSON round-trip through the project file.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23327
2026-03-06 12:05:57 -08:00
Seth Hillbrand e541232848 ERC: flag local labels with no local component pin connections
A local label that only connects to other labels or hierarchical sheet
pins without any component pin on the same sheet serves no local purpose
and is likely mislabeled. Extend the existing bus-member check to all
local labels so that ercCheckLabels() flags these cases as
ERCE_LABEL_NOT_CONNECTED.

The allPins > 1 guard prevents double-reporting with
ERCE_LABEL_SINGLE_PIN which already covers the allPins == 1 case.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23346
2026-03-06 11:53:09 -08:00
Seth Hillbrand fb1cab3e07 Fix "Save Library As" writing empty symbol library files
cacheLib() was unconditionally calling Load() for new caches even when
buffering was enabled, introduced by e013691d02 to fix issue #22191.
This broke "Save Library As" because the target file doesn't exist yet,
causing Load() to throw IO_ERROR. The exception was caught but no
symbols were added to the cache, resulting in an empty file

Additionally, the unbuffered library save path was passing the library
nickname instead of the target file path to the plugin's LoadSymbol/
SaveSymbol calls. While this was always wrong, it was masked before
e013691d02 because buffering mode skipped Load() entirely.

Fix cacheLib() to only call Load() for new caches when the library file
actually exists on disk, and fix the unbuffered save path to use the
target file path.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23337
2026-03-06 11:26:39 -08:00
Seth Hillbrand 31d1c09f24 PADS importer: fix pad shapes, zones, netclasses
PADSTACK in NORMAL mode stores one shape for all layers. When front
and back copper have different shapes, the second convertPadShape()
call overwrites the first. Pre-scanning copper layers and switching
to FRONT_INNER_BACK mode when shapes differ fixes this.

PADS stores connection style per-pin, not per-zone. The zone default
was THERMAL; it is now FULL (solid). Per-pad THERMAL overrides are
set from RT/ST thermal relief entries in the pad stack, carrying
over spoke width and angle.

The parser read NET_CLASS names and memberships but skipped per-class
RULE_SET entries for clearance and track width. RULE_SET parsing now
handles non-default rule sets and matches them to netclasses via the
FOR/NET_CLASS declaration.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23352
2026-03-06 11:25:54 -08:00
Seth Hillbrand 3d6886ef12 IPC-2581: add Content/BomRef and Content/AvlRef elements
The Bom and Avl top-level sections were emitted without corresponding
BomRef/AvlRef elements in the Content section, which IPC-2581C 4.1.1.2
requires as cross-references. Insert them in schema order after
LayerRef and before Dictionary elements.
2026-03-05 19:49:21 -08:00
Seth Hillbrand 03f2b6ee5a IPC-2581: fix OtherSideView element ordering and missing Package Outline
OtherSideView was appended to Package during courtyard processing,
before Pin elements, violating the IPC-2581C schema sequence. Build
it off-tree and attach after all Pin elements.

Also fix packages without a primary courtyard missing the required
Outline element by always emitting a bounding hull fallback when the
primary courtyard is empty.
2026-03-05 19:49:21 -08:00
Seth Hillbrand 7e4c55bd6f IPC-2581: synthesize stable refdes for footprints with empty references
Footprints with blank references produced schema-invalid XML with empty
refDes, RefDes/@name, and PinRef/@componentRef attributes. Generate a
stable UUID-based identifier when GetReference() is empty.
2026-03-05 19:49:21 -08:00
Seth Hillbrand ee346e1cf3 Fix rule editor handling of layer-scoped DRC rules
The text-based rule editor incorrectly warned about "duplicate conditions"
when two rules shared the same condition expression but had different layer
scopes (e.g., "(layer outer)" vs "(layer inner)"). Include the layer source
in the deduplication key so layer-differentiated rules are not flagged.

The graphical rule editor's save path had three related issues:
generateLayerClause() emitted multi-token "(layer "F.Cu" "B.Cu")" format
that the parser cannot handle (it expects a single token). Now detects
ExternalCuMask/InternalCuMask and emits "(layer outer)"/"(layer inner)".
The merge grouping key only used (ruleName, condition), causing rules with
different layer scopes to be incorrectly merged. Now includes layerSource.
The same-name validation in the graphical editor also excluded layer scope.

Add regression test verifying EvalRules returns correct per-layer clearances
for layer-scoped custom rules and zone fill produces no DRC violations.
2026-03-05 16:20:50 -08:00
Seth Hillbrand 01367187ef Fix creepage DRC arc paths and node connectivity
Two bugs caused the creepage checker to miss violations through arcs.
segmentIntersectsArc did not exclude shared-endpoint intersections,
so paths starting at arc endpoints were incorrectly rejected as
crossing a board edge, unlike segments_intersect which already had
this exclusion. The temp_nodes filter in testCreepage also had
inverted conditions, leaving ConnectChildren unreachable and
preventing point-on-arc nodes from linking to their parent arc
surface.

Adds a regression test with a slot between HV and GND pads requiring
8mm creepage distance.
2026-03-05 12:27:38 -08:00
Seth Hillbrand 073200bcf2 Fix format specifier in VCS test fixture
wxGetProcessId() returns long, not int. The %d
specifier triggered wxArgNormalizer assertions in
debug builds on every VCS test case.
2026-03-05 11:18:20 -08:00
Seth Hillbrand c9f67e6fb6 Fix creepage DRC failing to detect violations around slots
Three bugs prevented creepage paths from navigating around board
edge shapes (segments, rectangles, polygons):

1. TransformEdgeToCreepShapes never called SetParent() for SEGMENT,
   RECTANGLE, and POLY shapes. Their CREEP_SHAPE parent remained
   nullptr, causing GeneratePaths to exclude them from all path
   generation since null-parent nodes were filtered out.

2. CU_SHAPE_SEGMENT never set m_pos (defaulting to 0,0) and
   GetRadius() returned 0. The distance filter in GeneratePaths
   compared center positions with a bounding sphere, so all
   segment-to-edge-point pairs were rejected as too far apart.
   Set m_pos to the segment midpoint and override GetRadius() to
   return half the segment length plus half the width.

3. GeneratePaths only generated work items between nodes of
   different parent BOARD_ITEMs. Nodes sharing the same parent
   (e.g. multiple edge segments of the same gr_rect slot) were
   never paired, so the algorithm could not route around slot
   geometry. Added same-parent pairing for nodes with different
   CREEP_SHAPE parents.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20480
2026-03-05 11:13:23 -08:00
Seth Hillbrand a58e14178e Fix PADS multi-unit symbol import
Connector pins (e.g. J12-1 through J12-53) were imported as
separate single-pin symbols instead of units of one shared
symbol. Add BuildMultiUnitConnectorSymbol which creates a
multi-unit LIB_SYMBOL where each unit has the connector decal
graphics and one pin with the correct number.

Multi-gate parts like TL082 (U1-A, U1-B) appeared as separate
symbols because AddHierarchicalReference was called with the
unsuffixed reference "U1-A" instead of the stripped "U1".

Also move the connector SetRef call to after ApplyPartAttributes,
which only strips alphabetic gate suffixes and would otherwise
override the base reference back to "J12-1".
2026-03-05 09:04:36 -08:00
Damjan Prerad e2ae384b0f DRC Rule Editor: fix via style matcher, silk conditions, and overlay panels 2026-03-05 14:34:49 +01:00
Damjan Prerad 2dd979611d DRC Rule Editor: Refactor routing width panel to use optimum +/- tolerance input 2026-03-05 14:34:41 +01:00
Seth Hillbrand 9c6f99e0dd Fix import lockup on non-PCB files
LAYER_RANGE enters an infinite loop when constructed with
layer_count < 2. The next_layer() arithmetic underflows,
producing unreachable termination values, so the iterator
increments forever. This happens during board import when a
file produces a board with zero copper layers.

Clamp layer_count to a minimum of 2 in the LAYER_RANGE
constructor since F_Cu and B_Cu are always present.

Add content validation to the Fabmaster plugin, which
previously accepted any .txt file based on extension alone.
CanReadBoard now scans for !-delimited rows containing
known Fabmaster column headers before claiming the file.
2026-03-04 17:37:03 -08:00
John Beard 113746dc81 Pcbnew: move PCB_TRACK types to a lightweight header
This lightens the load when including forwards for PCB_TRACK and
friends as we don't need all the transitive includes. Sometimes
you just need the enums - many users just wanted VIATYPE, or
just needed a forward.

And reduces transitive code churn when something is changed in the
header - this reduces the files affected by a change in
pcb_track.h from nearly 400 to under 200.
2026-03-04 23:28:31 +08:00
John Beard 0365973c0b QA PNS: fix Boost init function signature
Not sure why this ever worked, it's been bool(void) for ages,
maybe they changed something in the header.
2026-03-04 23:25:10 +08:00
Seth Hillbrand fff428dcd6 Add THROTTLE class and DrainPendingEvents
Five call sites independently reimplemented the same
time-gated throttle pattern.  This consolidates them all
into a single THROTTLE class backed by steady_clock.

Three call sites duplicated the wxWidgets YieldFor workaround
for timer-event backlog (wxWidgets issue #26192). This replaces them
with a shared DrainPendingEvents free function.
2026-03-03 11:33:10 -08:00
Damjan Prerad 4836d172c7 Fix empty project name in symbol and sheet instances
Virtual root sheet set symbol and sheet instance projectnames
to be saved as empty strings. SCH_SHEET_PATH::Path()
skips the virtual root, so instance paths never start
with niluuid. Existing root UUID comparison was dead
code.

Use GetTopLevelSheets() to find current project instances
when the root is virtual and do direct root UUID comparison
for non-virtual roots. At save time, populate the project
name from GetProjectName() for current project instances
instead of using the stored (empty) m_ProjectName.

This fixes project rename not updating instance data,
and broken cross-project sheet sharing.
2026-03-03 19:55:52 +01:00
Damjan Prerad 038d635c02 DRC Rule Editor: Fix DRC Rule Editor related test failures 2026-03-03 19:09:58 +01:00
Seth Hillbrand 2d6db2ffc4 pcbnew: Fix multichannel topology with global nets
When hierarchical pins connect to global power nets, the multichannel
repeat-layout tool incorrectly reports a topology mismatch. The net
isomorphism algorithm treats global nets as channel-internal, causing
two failures: connection counts differ when global net pads are shared
with external components, and net-consistency checks flag false
contradictions between channels. The fix identifies nets whose
footprints fall outside the channel's footprint set and excludes them
from connection building and net-consistency checks. Global power rails
do not define internal channel routing topology, so this is correct.

Adds a QA regression test and reproduction board.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21739
2026-03-02 10:54:41 -08:00
Seth Hillbrand 6b8479c967 Fix pin connectivity when junction is at wire midpoint
A junction placed at the midpoint of a wire (without the wire being
split) now correctly connects all wires meeting at that point. The
connection graph previously only connected wires at their endpoints,
so a horizontal wire passing through a junction as a midpoint was not
linked to the vertical wire terminating at the junction.

The fix adds a special case in updateItemConnectivity() that, when
processing a junction item, queries GetBusesAndWires() with
aIgnoreEndpoints=true to find wires whose midpoints coincide with the
junction. These wires are added to the connection map at the junction
position, mirroring the existing label-at-wire-midpoint handling.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23143
2026-03-02 10:54:41 -08:00
Seth Hillbrand 2c63082a3d Fix drill report file crash when board has drills
When the fmt migration (77e42a151b) converted gendrill report writing
from richio OUTPUTFORMATTER to fmt::print, the first argument to
Out.Print() was an indentation level (integer 0), not the FILE*.
The migration preserved the literal 0 as the first argument to
fmt::print(), passing a null FILE* and causing a SIGSEGV the first
time any drill tool was written to the report.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/23289
2026-03-01 22:13:00 -08:00
John Beard 16bcaff33f Allegro QA: Print error messages from load in the test message log 2026-03-01 22:54:04 +08:00
John Beard 76ac4883b4 Allegro QA: Fix outline test
This now imported as a single rectangle, not 4 segments.

Genericise the test to handle more kinds of outlines.
2026-03-01 18:10:13 +08:00
John Beard 8f8dd66cb6 Pcbnew QA: Add an expectation for graphical circles on boards 2026-02-28 20:41:04 +08:00
John Beard ab430d2683 Pcbnew QA: init WX in pcbnew_tools
This allows, for example, logging/tracing to work.
2026-02-28 20:41:04 +08:00