KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_reannotate_tool.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 (C) 2020 Brian Piccioni [email protected]
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Brian Piccioni <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
23
24#include <wx/filedlg.h>
25
26#include <footprint.h>
27#include <pcb_group.h>
28#include <refdes_utils.h>
29#include <string_utils.h>
30#include <tool/tool_manager.h>
31
32
34 PCB_TOOL_BASE( "pcbnew.ReannotateTool" ),
35 m_selectionTool( nullptr ),
36 m_frame( nullptr )
37{
38}
39
40
42{
43 // Find the selection tool, so they can cooperate
45
46 return true;
47}
48
49
54
55
57{
59 dialog.ShowModal();
60 return 0;
61}
62
63
65{
66 PCB_SELECTION& selection = m_selectionTool->GetSelection();
67
68 if( selection.Empty() )
69 return 0;
70
71 return ReannotateDuplicates( selection, std::vector<EDA_ITEM*>() );
72}
73
75 const std::vector<EDA_ITEM*>& aAdditionalFootprints )
76{
77 if( aSelectionToReannotate.Empty() )
78 return 0;
79
80 // 1. Build list of designators on the board & the additional footprints
81 FOOTPRINTS fpOnBoard = m_frame->GetBoard()->Footprints();
82 std::multimap<wxString, KIID> usedDesignatorsMap;
83
84 for( EDA_ITEM* item : aAdditionalFootprints )
85 {
86 if( item->Type() == PCB_FOOTPRINT_T )
87 fpOnBoard.push_back( static_cast<FOOTPRINT*>( item ) );
88
89 if( item->Type() == PCB_GROUP_T )
90 {
91 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
92
93 group->RunOnChildren(
94 [&]( BOARD_ITEM* aGroupItem )
95 {
96 if( aGroupItem->Type() == PCB_FOOTPRINT_T )
97 fpOnBoard.push_back( static_cast<FOOTPRINT*>( aGroupItem ) );
98 },
100 }
101 }
102
103 for( FOOTPRINT* fp : fpOnBoard )
104 usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
105
106 // 2. Get a sorted list of footprints from the selection
107 FOOTPRINTS fpInSelection;
108
109 for( EDA_ITEM* item : aSelectionToReannotate )
110 {
111 if( item->Type() == PCB_FOOTPRINT_T )
112 fpInSelection.push_back( static_cast<FOOTPRINT*>( item ) );
113
114 if( item->Type() == PCB_GROUP_T )
115 {
116 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
117
118 group->RunOnChildren(
119 [&]( BOARD_ITEM* aGroupItem )
120 {
121 if( aGroupItem->Type() == PCB_FOOTPRINT_T )
122 fpInSelection.push_back( static_cast<FOOTPRINT*>( aGroupItem ) );
123 },
125 }
126 }
127
128 std::sort( fpInSelection.begin(), fpInSelection.end(),
129 []( const FOOTPRINT* aA, const FOOTPRINT* aB ) -> bool
130 {
131 int ii = StrNumCmp( aA->GetReference(), aB->GetReference(), true );
132
133 if( ii == 0 )
134 {
135 // Sort by position: x, then y
136 if( aA->GetPosition().y == aB->GetPosition().y )
137 {
138 if( aA->GetPosition().x == aB->GetPosition().x )
139 return aA->m_Uuid < aB->m_Uuid; // ensure a deterministic sort
140 else
141 return aA->GetPosition().x < aB->GetPosition().x;
142 }
143 else
144 {
145 return aA->GetPosition().y > aB->GetPosition().y;
146 }
147 }
148
149 return ii < 0;
150 } );
151
152 // 3. Iterate through the sorted list of footprints
153 for( FOOTPRINT* fp : fpInSelection )
154 {
155 wxString stem = UTIL::GetRefDesPrefix( fp->GetReference() );
156 int value = UTIL::GetRefDesNumber( fp->GetReference() );
157 bool duplicate = false;
158
159 while( usedDesignatorsMap.find( fp->GetReference() ) != usedDesignatorsMap.end() )
160 {
161 auto result = usedDesignatorsMap.equal_range( fp->GetReference() );
162
163 for( auto& it = result.first; it != result.second; it++ )
164 {
165 if( it->second != fp->m_Uuid )
166 {
167 duplicate = true;
168 break;
169 }
170 }
171
172 if( !duplicate )
173 break; // The only designator in the board with this reference is the selected one
174
175 if( value < 0 )
176 value = 1;
177 else
178 ++value;
179
180 fp->SetReference( stem + std::to_string( value ) );
181 }
182
183 if( duplicate )
184 usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
185 }
186
187 return 0;
188}
189
190
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:81
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int ReannotateDuplicates(const PCB_SELECTION &aSelectionToReannotate, const std::vector< EDA_ITEM * > &aAdditionalFootprints)
PCB_SELECTION_TOOL * m_selectionTool
int ShowReannotateDialog(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
int ShowModal() override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
static TOOL_ACTION boardReannotate
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:49
The selection tool: currently supports:
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
const PCB_SELECTION & selection() const
bool Empty() const
Checks if there is anything selected.
Definition selection.h:111
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
Generic, UI-independent tool event.
Definition tool_event.h:167
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
@ RECURSE
Definition eda_item.h:49
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
int GetRefDesNumber(const wxString &aRefDes)
Get the numeric suffix from a refdes - e.g.
Class to handle a set of BOARD_ITEMs.
std::deque< FOOTPRINT * > FOOTPRINTS
Collection of utility functions for component reference designators (refdes)
wxString result
Test unit parsing edge cases and error handling.
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:104
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:79