1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2019 CERN
5 * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.TXT for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25 #include <tools/ee_selection.h>
26 #include <sch_item.h>
27 #include <sch_reference_list.h>
28 #include <sch_sheet_path.h>
29 #include <sch_symbol.h>
30 #include <sch_sheet.h>
31
32
EE_SELECTION(SCH_SCREEN * aScreen)33 EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) :
34 SELECTION()
35 {
36 m_screen = aScreen;
37 }
38
39
GetTopLeftItem(bool onlyModules) const40 EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
41 {
42 EDA_ITEM* topLeftItem = nullptr;
43 wxPoint topLeftPos;
44
45 // find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item
46 // in the selection
47 for( EDA_ITEM* item : m_items )
48 {
49 wxPoint pos = item->GetPosition();
50
51 if( ( topLeftItem == nullptr )
52 || ( pos.x < topLeftPos.x )
53 || ( topLeftPos.x == pos.x && pos.y < topLeftPos.y ) )
54 {
55 topLeftItem = item;
56 topLeftPos = pos;
57 }
58 }
59
60 return topLeftItem;
61 }
62
63
GetBoundingBox() const64 EDA_RECT EE_SELECTION::GetBoundingBox() const
65 {
66 EDA_RECT bbox;
67
68 for( EDA_ITEM* item : m_items )
69 {
70 if( item->Type() == SCH_SYMBOL_T )
71 {
72 // Quiet Coverity warning. The LIB_SYMBOL field container is a Boost ptr_vector
73 // so the exception is legit.
74 try
75 {
76 bbox.Merge( static_cast<SCH_SYMBOL*>( item )->GetBoundingBox() );
77 }
78 catch( const boost::bad_pointer& exc )
79 {
80 wxFAIL_MSG( "Invalid pointer." );
81 }
82 }
83 else if( item->Type() == SCH_SHEET_T )
84 {
85 bbox.Merge( static_cast<SCH_SHEET*>( item )->GetBodyBoundingBox() );
86 }
87 else
88 {
89 bbox.Merge( item->GetBoundingBox() );
90 }
91 }
92
93 return bbox;
94 }
95
96
GetSymbols(SCH_REFERENCE_LIST & aReferences,const SCH_SHEET_PATH & aSelectionPath,bool aIncludePowerSymbols,bool aForceIncludeOrphanSymbols)97 void EE_SELECTION::GetSymbols( SCH_REFERENCE_LIST& aReferences,
98 const SCH_SHEET_PATH& aSelectionPath,
99 bool aIncludePowerSymbols,
100 bool aForceIncludeOrphanSymbols )
101 {
102 for( EDA_ITEM* item : Items() )
103 {
104 if( item->Type() != SCH_SYMBOL_T )
105 continue;
106
107 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
108 aSelectionPath.AppendSymbol( aReferences, symbol, aIncludePowerSymbols,
109 aForceIncludeOrphanSymbols );
110 }
111 }
112
113
GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP & aRefList,const SCH_SHEET_PATH & aSelectionPath,bool aIncludePowerSymbols)114 void EE_SELECTION::GetMultiUnitSymbols( SCH_MULTI_UNIT_REFERENCE_MAP& aRefList,
115 const SCH_SHEET_PATH& aSelectionPath,
116 bool aIncludePowerSymbols )
117 {
118 for( EDA_ITEM* item : Items() )
119 {
120 if( item->Type() != SCH_SYMBOL_T )
121 continue;
122
123 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
124 aSelectionPath.AppendMultiUnitSymbol( aRefList, symbol, aIncludePowerSymbols );
125 }
126 }
127
128
AllItemsHaveLineStroke() const129 bool EE_SELECTION::AllItemsHaveLineStroke() const
130 {
131 for( const EDA_ITEM* item : m_items )
132 {
133 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
134
135 if( !schItem || !schItem->HasLineStroke() )
136 return false;
137 }
138
139 return true;
140 }
141