KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue24967.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <board.h>
23#include <pcb_group.h>
24#include <pcb_track.h>
25#include <pcb_view.h>
26#include <tool/tool_manager.h>
28
29// Regression test for https://gitlab.com/kicad/code/kicad/-/work_items/24967
30//
31// Expanding a connection from a segment inside a group walked the whole net and called select()
32// on segments outside the group. select() reacts to an out-of-scope item by ExitGroup(), which
33// clears the selection and drops the entered-group context mid-walk, and a later Delete then
34// promoted the survivors back to the whole group and wiped it. Expansion must stay within the
35// entered group.
36
37BOOST_AUTO_TEST_SUITE( Issue24967 )
38
39
40static PCB_TRACK* addSegment( BOARD& aBoard, const VECTOR2I& aStart, const VECTOR2I& aEnd )
41{
42 PCB_TRACK* track = new PCB_TRACK( &aBoard );
43 track->SetLayer( F_Cu );
44 track->SetWidth( 250000 );
45 track->SetStart( aStart );
46 track->SetEnd( aEnd );
47 aBoard.Add( track );
48 return track;
49}
50
51
52BOOST_AUTO_TEST_CASE( ExpansionStaysInsideEnteredGroup )
53{
54 // view must outlive board so board items unregister from a live view at teardown.
55 KIGFX::PCB_VIEW view;
56 BOARD board;
57 TOOL_MANAGER mgr;
58 mgr.SetEnvironment( &board, &view, nullptr, nullptr, nullptr );
59
61 mgr.RegisterTool( selTool );
62
63 // A-B-C-D chain, only the middle segment is grouped.
64 PCB_TRACK* segAB = addSegment( board, { 0, 0 }, { 1000000, 0 } );
65 PCB_TRACK* segBC = addSegment( board, { 1000000, 0 }, { 2000000, 0 } );
66 PCB_TRACK* segCD = addSegment( board, { 2000000, 0 }, { 3000000, 0 } );
67
68 PCB_GROUP* group = new PCB_GROUP( &board );
69 group->AddItem( segBC );
70 board.Add( group );
71
72 board.BuildConnectivity();
73
74 for( PCB_TRACK* track : { segAB, segBC, segCD } )
75 view.Add( track );
76
77 view.Add( group );
78
79 // Enter the group and start from the grouped segment, as a double-click + U would.
80 selTool->AddItemToSel( group, true );
81 selTool->EnterGroup();
82 BOOST_REQUIRE_EQUAL( selTool->GetEnteredGroup(), group );
83
84 std::vector<BOARD_CONNECTED_ITEM*> startItems = { segBC };
86
87 // Expansion must not escape the group: it stays entered and the ungrouped ends are untouched.
89 BOOST_CHECK( !segAB->IsSelected() );
90 BOOST_CHECK( !segCD->IsSelected() );
91}
92
93
94BOOST_AUTO_TEST_CASE( ExpansionFromOutsideLeavesGroupIntact )
95{
96 // view must outlive board so board items unregister from a live view at teardown.
97 KIGFX::PCB_VIEW view;
98 BOARD board;
99 TOOL_MANAGER mgr;
100 mgr.SetEnvironment( &board, &view, nullptr, nullptr, nullptr );
101
103 mgr.RegisterTool( selTool );
104
105 // A-B-C-D chain, only the middle segment is grouped.
106 PCB_TRACK* segAB = addSegment( board, { 0, 0 }, { 1000000, 0 } );
107 PCB_TRACK* segBC = addSegment( board, { 1000000, 0 }, { 2000000, 0 } );
108 PCB_TRACK* segCD = addSegment( board, { 2000000, 0 }, { 3000000, 0 } );
109
110 PCB_GROUP* group = new PCB_GROUP( &board );
111 group->AddItem( segBC );
112 board.Add( group );
113
114 board.BuildConnectivity();
115
116 for( PCB_TRACK* track : { segAB, segBC, segCD } )
117 view.Add( track );
118
119 view.Add( group );
120
121 // Not entered: expand from an ungrouped segment, as a single-click + U would.
122 std::vector<BOARD_CONNECTED_ITEM*> startItems = { segAB };
124
125 // Expansion must not reach into the group. The ungrouped ends are selected, but the grouped
126 // segment stays unselected so a following delete can't take the whole group.
127 BOOST_CHECK_EQUAL( selTool->GetEnteredGroup(), nullptr );
128 BOOST_CHECK( segAB->IsSelected() );
129 BOOST_CHECK( segCD->IsSelected() );
130 BOOST_CHECK( !segBC->IsSelected() );
131}
132
133
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1355
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition board.cpp:202
bool IsSelected() const
Definition eda_item.h:132
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition pcb_view.cpp:53
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:51
The selection tool: currently supports:
void EnterGroup() override
Enter the group at the head of the current selection.
PCB_GROUP * GetEnteredGroup()
void selectAllConnectedTracks(const std::vector< BOARD_CONNECTED_ITEM * > &aStartItems, STOP_CONDITION aStopCondition)
Select connected tracks and vias.
@ STOP_NEVER
Select the entire net.
void SetEnd(const VECTOR2I &aEnd)
Definition pcb_track.h:89
void SetStart(const VECTOR2I &aStart)
Definition pcb_track.h:92
virtual void SetWidth(int aWidth)
Definition pcb_track.h:86
int AddItemToSel(const TOOL_EVENT &aEvent)
Master controller class:
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
@ F_Cu
Definition layer_ids.h:60
Class to handle a set of BOARD_ITEMs.
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ExpansionStaysInsideEnteredGroup)
static PCB_TRACK * addSegment(BOARD &aBoard, const VECTOR2I &aStart, const VECTOR2I &aEnd)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683