KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue24335_group_move_ancestor.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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 */
20
36
37#include <boost/test/unit_test.hpp>
38
39#include <eda_item.h>
40#include <sch_field.h>
41#include <sch_group.h>
42#include <sch_line.h>
43#include <sch_screen.h>
44#include <sch_symbol.h>
45#include <schematic.h>
47
49
50#include <wx/filename.h>
51#include <wx/stdpaths.h>
52
53
55{
58 {
59 wxString tempDir = wxStandardPaths::Get().GetTempDir();
60 wxString projectPath = tempDir + wxFileName::GetPathSeparator()
61 + wxT( "test_issue24335.kicad_pro" );
62 m_tempFiles.push_back( projectPath );
63
64 m_settingsManager.LoadProject( projectPath.ToStdString() );
65 m_schematic = std::make_unique<SCHEMATIC>( nullptr );
66 m_schematic->SetProject( &m_settingsManager.Prj() );
67 m_schematic->CreateDefaultScreens();
68 }
69
71 {
72 m_schematic.reset();
73
74 for( const wxString& file : m_tempFiles )
75 {
76 if( wxFileExists( file ) )
77 wxRemoveFile( file );
78 }
79 }
80
82 std::unique_ptr<SCHEMATIC> m_schematic;
83 std::vector<wxString> m_tempFiles;
84};
85
86
87BOOST_FIXTURE_TEST_SUITE( Issue24335GroupMoveAncestor, GROUP_MOVE_ANCESTOR_FIXTURE )
88
89
90BOOST_AUTO_TEST_CASE( SymbolInsideSelectedGroupReportsAncestor )
91{
92 SCH_SCREEN* screen = m_schematic->GetTopLevelSheets()[0]->GetScreen();
93 BOOST_REQUIRE( screen );
94
95 SCH_SYMBOL* symbol = new SCH_SYMBOL();
96 symbol->SetPosition( VECTOR2I( 0, 0 ) );
97 screen->Append( symbol );
98
99 SCH_GROUP* group = new SCH_GROUP( screen );
100 group->AddItem( symbol );
101 screen->Append( group );
102
103 // Baseline: nothing is selected.
104 BOOST_CHECK( !symbol->IsSelected() );
105 BOOST_CHECK( !symbol->HasSelectedAncestorGroup() );
106
107 // Selecting the group must propagate to "ancestor is selected" for the symbol even though the
108 // symbol itself does not carry the SELECTED flag (group selection replaces members in the
109 // collector).
110 group->SetSelected();
111
112 BOOST_CHECK( !symbol->IsSelected() );
113 BOOST_CHECK( symbol->HasSelectedAncestorGroup() );
114
115 group->ClearSelected();
116 BOOST_CHECK( !symbol->HasSelectedAncestorGroup() );
117}
118
119
120BOOST_AUTO_TEST_CASE( NestedGroupAncestorIsDetected )
121{
122 SCH_SCREEN* screen = m_schematic->GetTopLevelSheets()[0]->GetScreen();
123 BOOST_REQUIRE( screen );
124
125 SCH_SYMBOL* symbol = new SCH_SYMBOL();
126 symbol->SetPosition( VECTOR2I( 0, 0 ) );
127 screen->Append( symbol );
128
129 SCH_GROUP* inner = new SCH_GROUP( screen );
130 inner->AddItem( symbol );
131 screen->Append( inner );
132
133 SCH_GROUP* outer = new SCH_GROUP( screen );
134 outer->AddItem( inner );
135 screen->Append( outer );
136
137 BOOST_REQUIRE( symbol->GetParentGroup() == inner );
138 BOOST_REQUIRE( inner->GetParentGroup() == outer );
139
140 // Selecting only the outer group must still be picked up by the symbol's ancestor walk.
141 outer->SetSelected();
142 BOOST_CHECK( symbol->HasSelectedAncestorGroup() );
143 BOOST_CHECK( inner->HasSelectedAncestorGroup() );
144
145 outer->ClearSelected();
146 inner->SetSelected();
147 BOOST_CHECK( symbol->HasSelectedAncestorGroup() );
148 BOOST_CHECK( !inner->HasSelectedAncestorGroup() );
149}
150
151
152BOOST_AUTO_TEST_CASE( SymbolFieldInheritsAncestorGroupViaParent )
153{
154 SCH_SCREEN* screen = m_schematic->GetTopLevelSheets()[0]->GetScreen();
155 BOOST_REQUIRE( screen );
156
157 // Symbol fields are children of the symbol (GetParent() == symbol). When the symbol's group
158 // is selected, the field must also be recognised as moving with the group via the parent walk.
159 SCH_SYMBOL* symbol = new SCH_SYMBOL();
160 symbol->SetPosition( VECTOR2I( 0, 0 ) );
161 screen->Append( symbol );
162
163 SCH_GROUP* group = new SCH_GROUP( screen );
164 group->AddItem( symbol );
165 screen->Append( group );
166
167 SCH_FIELD* field = symbol->GetField( FIELD_T::REFERENCE );
168 BOOST_REQUIRE( field );
169 BOOST_REQUIRE( field->GetParent() == symbol );
170 BOOST_REQUIRE( field->GetParentGroup() == nullptr );
171
172 group->SetSelected();
173
174 BOOST_CHECK( field->HasSelectedAncestorGroup() );
175}
176
177
178BOOST_AUTO_TEST_CASE( WireInsideSelectedGroupReportsAncestor )
179{
180 SCH_SCREEN* screen = m_schematic->GetTopLevelSheets()[0]->GetScreen();
181 BOOST_REQUIRE( screen );
182
183 SCH_LINE* wire = new SCH_LINE( VECTOR2I( 0, 0 ), LAYER_WIRE );
184 wire->SetEndPoint( VECTOR2I( 100000, 0 ) );
185 screen->Append( wire );
186
187 SCH_GROUP* group = new SCH_GROUP( screen );
188 group->AddItem( wire );
189 screen->Append( group );
190
191 group->SetSelected();
192
193 // The connectivity walker relies on this signal to avoid double-moving in-group wires.
194 BOOST_CHECK( wire->HasSelectedAncestorGroup() );
195}
196
197
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:62
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:118
void ClearSelected()
Definition eda_item.h:151
bool IsSelected() const
Definition eda_item.h:136
void SetSelected()
Definition eda_item.h:148
EDA_ITEM * GetParent() const
Definition eda_item.h:114
bool HasSelectedAncestorGroup() const
Definition eda_item.cpp:110
A set of SCH_ITEMs (i.e., without duplicates).
Definition sch_group.h:52
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:42
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:149
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Schematic symbol object.
Definition sch_symbol.h:73
void SetPosition(const VECTOR2I &aPosition) override
Definition sch_symbol.h:890
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
@ LAYER_WIRE
Definition layer_ids.h:454
Class to handle a set of SCH_ITEMs.
@ REFERENCE
Field Reference of part, i.e. "IC21".
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(SymbolInsideSelectedGroupReportsAncestor)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687