KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 brian@documenteddesigns.com
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Brian Piccioni <brian@documenteddesigns.com>
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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <pcb_group.h>
27#include <refdes_utils.h>
28#include <string_utils.h>
29#include <tool/tool_manager.h>
30#include <wx/filedlg.h>
32
33
35 PCB_TOOL_BASE( "pcbnew.ReannotateTool" ),
36 m_selectionTool( nullptr ),
37 m_frame( nullptr )
38{
39}
40
41
43{
44 // Find the selection tool, so they can cooperate
46
47 return true;
48}
49
50
52{
53 m_frame = getEditFrame<PCB_EDIT_FRAME>();
54}
55
56
58{
60 dialog.ShowModal();
61 return 0;
62}
63
64
66{
68
69 if( selection.Empty() )
70 return 0;
71
72 return ReannotateDuplicates( selection, std::vector<EDA_ITEM*>() );
73}
74
76 const std::vector<EDA_ITEM*>& aAdditionalFootprints )
77{
78 if( aSelectionToReannotate.Empty() )
79 return 0;
80
81 // 1. Build list of designators on the board & the additional footprints
82 FOOTPRINTS fpOnBoard = m_frame->GetBoard()->Footprints();
83 std::multimap<wxString, KIID> usedDesignatorsMap;
84
85 for( EDA_ITEM* item : aAdditionalFootprints )
86 {
87 if( item->Type() == PCB_FOOTPRINT_T )
88 fpOnBoard.push_back( static_cast<FOOTPRINT*>( item ) );
89
90 if( item->Type() == PCB_GROUP_T )
91 {
92 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
93
94 group->RunOnChildren(
95 [&]( BOARD_ITEM* aGroupItem )
96 {
97 if( aGroupItem->Type() == PCB_FOOTPRINT_T )
98 fpOnBoard.push_back( static_cast<FOOTPRINT*>( aGroupItem ) );
99 },
100 RECURSE_MODE::RECURSE );
101 }
102 }
103
104 for( FOOTPRINT* fp : fpOnBoard )
105 usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
106
107 // 2. Get a sorted list of footprints from the selection
108 FOOTPRINTS fpInSelection;
109
110 for( EDA_ITEM* item : aSelectionToReannotate )
111 {
112 if( item->Type() == PCB_FOOTPRINT_T )
113 fpInSelection.push_back( static_cast<FOOTPRINT*>( item ) );
114
115 if( item->Type() == PCB_GROUP_T )
116 {
117 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
118
119 group->RunOnChildren(
120 [&]( BOARD_ITEM* aGroupItem )
121 {
122 if( aGroupItem->Type() == PCB_FOOTPRINT_T )
123 fpInSelection.push_back( static_cast<FOOTPRINT*>( aGroupItem ) );
124 },
125 RECURSE_MODE::RECURSE );
126 }
127 }
128
129 std::sort( fpInSelection.begin(), fpInSelection.end(),
130 []( const FOOTPRINT* aA, const FOOTPRINT* aB ) -> bool
131 {
132 int ii = StrNumCmp( aA->GetReference(), aB->GetReference(), true );
133
134 if( ii == 0 )
135 {
136 // Sort by position: x, then y
137 if( aA->GetPosition().y == aB->GetPosition().y )
138 {
139 if( aA->GetPosition().x == aB->GetPosition().x )
140 return aA->m_Uuid < aB->m_Uuid; // ensure a deterministic sort
141 else
142 return aA->GetPosition().x < aB->GetPosition().x;
143 }
144 else
145 {
146 return aA->GetPosition().y > aB->GetPosition().y;
147 }
148 }
149
150 return ii < 0;
151 } );
152
153 // 3. Iterate through the sorted list of footprints
154 for( FOOTPRINT* fp : fpInSelection )
155 {
156 wxString stem = UTIL::GetRefDesPrefix( fp->GetReference() );
157 int value = UTIL::GetRefDesNumber( fp->GetReference() );
158 bool duplicate = false;
159
160 while( usedDesignatorsMap.find( fp->GetReference() ) != usedDesignatorsMap.end() )
161 {
162 auto result = usedDesignatorsMap.equal_range( fp->GetReference() );
163
164 for( auto& it = result.first; it != result.second; it++ )
165 {
166 if( it->second != fp->m_Uuid )
167 {
168 duplicate = true;
169 break;
170 }
171 }
172
173 if( !duplicate )
174 break; // The only designator in the board with this reference is the selected one
175
176 if( value < 0 )
177 value = 1;
178 else
179 ++value;
180
181 fp->SetReference( stem + std::to_string( value ) );
182 }
183
184 if( duplicate )
185 usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
186 }
187
188 return 0;
189}
190
191
193{
195}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:78
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.
const FOOTPRINTS & Footprints() const
Definition: board.h:338
int ShowModal() override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:95
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:107
static TOOL_ACTION boardReannotate
Definition: pcb_actions.h:568
BOARD * GetBoard() const
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:52
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
const PCB_SELECTION & selection() const
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:168
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).
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.
Collection of utility functions for component reference designators (refdes)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:110
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86