KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_board_reannotate.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, 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
27
28#include <algorithm>
29#include <base_units.h>
30#include <bitmaps.h>
31#include <board_commit.h>
32#include <confirm.h>
33#include <ctype.h>
35#include <string_utils.h> // StrNumCmp
36#include <kiface_base.h>
37#include <pcbnew_settings.h>
38#include <refdes_utils.h>
39#include <richio.h>
40#include <tool/grid_menu.h>
42#include <wx/valtext.h>
43
44
48
49//
50// This converts the index into a sort code. Note that Back sort code will have left and
51// right swapped.
52//
54 SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Top to bottom, left to right", // 100
55 SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Top to bottom, right to left", // 101
56 SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Back to Front, left to right", // 110
57 SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Back to Front, right to left", // 111
58 SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Left to right, Front to Back", // 000
59 SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Left to right, Back to Front", // 001
60 SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Right to left, Front to Back", // 010
61 SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND // "Right to left, Back to Front", // 011
62};
63
64
65//
66// Back Left/Right is opposite because it is a mirror image (coordinates are from the top)
67//
69 SORTYFIRST + ASCENDINGFIRST + DESCENDINGSECOND, // "Top to bottom, left to right", // 101
70 SORTYFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Top to bottom, right to left", // 100
71 SORTYFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Bottom to top, left to right", // 111
72 SORTYFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Bottom to top, right to left", // 110
73 SORTXFIRST + DESCENDINGFIRST + ASCENDINGSECOND, // "Left to right, top to bottom", // 010
74 SORTXFIRST + DESCENDINGFIRST + DESCENDINGSECOND, // "Left to right, bottom to top", // 011
75 SORTXFIRST + ASCENDINGFIRST + ASCENDINGSECOND, // "Right to left, top to bottom", // 000
76 SORTXFIRST + ASCENDINGFIRST + DESCENDINGSECOND // "Right to left, bottom to top", // 001
77};
78
79#define SetSortCodes( DirArray, Code ) \
80 { \
81 g_SortYFirst = ( ( DirArray[Code] & SORTYFIRST ) != 0 ); \
82 g_DescendingFirst = ( ( DirArray[Code] & DESCENDINGFIRST ) != 0 ); \
83 g_DescendingSecond = ( ( DirArray[Code] & DESCENDINGSECOND ) != 0 ); \
84 }
85
86
87wxString ActionMessage[] = {
88 "", // UPDATE_REFDES
89 _( "Empty" ), // EMPTY_REFDES
90 _( "Invalid" ), // INVALID_REFDES
91 _( "Excluded" ) // EXCLUDE_REFDES
92};
93
94
96 DIALOG_BOARD_REANNOTATE_BASE( aParentFrame ),
97 m_frame( aParentFrame ),
98 m_footprints( aParentFrame->GetBoard()->Footprints() )
99{
100 // Init bitmaps associated to some wxRadioButton
101 reannotate_down_right_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_right_down ) );
102 reannotate_right_down_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_left_down ) );
103 reannotate_down_left_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_right_up ) );
104 reannotate_left_down_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_left_up ) );
105 reannotate_up_right_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_down_left ) );
106 reannotate_right_up_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_up_left ) );
107 reannotate_up_left_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_down_right ) );
108 reannotate_left_up_bitmap->SetBitmap( KiBitmapBundle( BITMAPS::reannotate_up_right ) );
109
110 m_FrontRefDesStart->SetValidator( wxTextValidator( wxFILTER_DIGITS ) );
111 m_BackRefDesStart->SetValidator( wxTextValidator( wxFILTER_DIGITS ) );
112
113 SetupStandardButtons( { { wxID_OK, _( "Reannotate PCB" ) },
114 { wxID_CANCEL, _( "Close" ) } } );
115
116 wxArrayString gridslist;
117 GRID_MENU::BuildChoiceList( &gridslist, m_frame->config(), aParentFrame );
118
119 m_GridChoice->Set( gridslist );
120
121 m_ExcludeList->SetToolTip( m_ExcludeListText->GetToolTipText() );
122 m_GridChoice->SetToolTip( m_SortGridText->GetToolTipText() );
123
124 m_MessageWindow->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
125
127}
128
129
130void DIALOG_BOARD_REANNOTATE::OnCloseClick( wxCommandEvent& event )
131{
132 EndDialog( wxID_OK );
133}
134
135
137{
138 PCB_SELECTION selection = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
139
140 if( !selection.Empty() )
141 m_AnnotateSelection->SetValue( true );
142
143 return true;
144}
145
146
147void DIALOG_BOARD_REANNOTATE::FilterPrefix( wxTextCtrl* aPrefix )
148{
149 std::string tmps = VALIDPREFIX;
150
151 if( aPrefix->GetValue().empty() )
152 return; //Should never happen
153
154 char lastc = aPrefix->GetValue().Last();
155
156 if( isalnum( (int) lastc ) )
157 return;
158
159 if( tmps.find( lastc ) != std::string::npos )
160 return;
161
162 tmps = aPrefix->GetValue();
163 aPrefix->Clear();
164 tmps.pop_back();
165 aPrefix->AppendText( tmps );
166}
167
168
170 int aStartRefDes )
171{
172 for( size_t i = 0; i < m_refDesPrefixInfos.size(); i++ ) // See if it is in the info array
173 {
174 if( m_refDesPrefixInfos[i].RefDesPrefix == aRefDesPrefix ) // Found it!
175 return &m_refDesPrefixInfos[i];
176 }
177
178 // Wasn't in the info array so add it
179 REFDES_PREFIX_INFO newtype;
180 newtype.RefDesPrefix = aRefDesPrefix;
181 newtype.LastUsedRefDes = aStartRefDes - 1;
182 m_refDesPrefixInfos.push_back( newtype );
183
184 return &m_refDesPrefixInfos.back();
185}
186
187
189{
191}
192
193
194void DIALOG_BOARD_REANNOTATE::FilterBackPrefix( wxCommandEvent& event )
195{
197}
198
199
200void DIALOG_BOARD_REANNOTATE::OnApplyClick( wxCommandEvent& event )
201{
203
204 if( ReannotateBoard() )
205 {
206 ShowReport( _( "PCB successfully reannotated" ), RPT_SEVERITY_ACTION );
207 ShowReport( _( "PCB annotation changes should be synchronized with schematic using "
208 "the \"Update Schematic from PCB\" tool." ), RPT_SEVERITY_WARNING );
209 }
210
212 m_MessageWindow->Flush( false );
213 m_frame->GetCanvas()->Refresh(); // Redraw
214 m_frame->OnModify(); // Need to save file on exit.
215}
216
217
218int DIALOG_BOARD_REANNOTATE::RoundToGrid( int aCoord, int aGrid )
219{
220 if( 0 == aGrid )
221 aGrid = MINGRID;
222
223 int rounder;
224 rounder = aCoord % aGrid;
225 aCoord -= rounder;
226
227 if( abs( rounder ) > ( aGrid / 2 ) )
228 aCoord += ( aCoord < 0 ? -aGrid : aGrid );
229
230 return ( aCoord );
231}
232
233
236static bool ChangeArrayCompare( const REFDES_CHANGE& aA, const REFDES_CHANGE& aB )
237{
238 return ( StrNumCmp( aA.OldRefDesString, aB.OldRefDesString ) < 0 );
239}
240
241
244static bool FootprintCompare( const REFDES_INFO& aA, const REFDES_INFO& aB )
245{
246 int X0 = aA.roundedx, X1 = aB.roundedx, Y0 = aA.roundedy, Y1 = aB.roundedy;
247
248 if( g_SortYFirst ) //If sorting by Y then X, swap X and Y
249 {
250 std::swap( X0, Y0 );
251 std::swap( X1, Y1 );
252 }
253
254 // If descending, same compare just swap directions
256 std::swap( X0, X1 );
257
259 std::swap( Y0, Y1 );
260
261 if( X0 < X1 )
262 return true; // yes, it's smaller
263 else if( X0 > X1 )
264 return false; // no, it's not
265 else if( Y0 < Y1 )
266 return true;
267 else
268 return false;
269}
270
271
273{
274 return wxString::Format( wxT( "%s, %s" ),
277}
278
279
280void DIALOG_BOARD_REANNOTATE::ShowReport( const wxString& aMessage, SEVERITY aSeverity )
281{
282 wxStringTokenizer msgs( aMessage, wxT( "\n" ) );
283
284 while( msgs.HasMoreTokens() )
285 m_MessageWindow->Report( msgs.GetNextToken(), aSeverity );
286}
287
288
290{
291 int i = 1;
292 wxString message;
293
294 message.Printf( _( "<br/>There are %i reference designator prefixes in use<br/>"
295 "**********************************************************<br/>" ),
296 (int) m_refDesPrefixInfos.size() );
297
298 for( const REFDES_PREFIX_INFO& info : m_refDesPrefixInfos ) // Show all the types of refdes
299 message += info.RefDesPrefix + ( ( i++ % 16 ) == 0 ? wxT( "<br/>" ) : wxS( " " ) );
300
301 message += wxT( "<br/>" );
302
303 if( !m_excludeArray.empty() )
304 {
305 wxString excludes;
306
307 for( wxString& exclude : m_excludeArray ) // Show the refdes we are excluding
308 excludes += exclude + wxS( " " );
309
310 message += wxString::Format( _( "Excluding: %s from reannotation<br/>" ), excludes );
311 }
312
313 message += _( "<br/>Change Array\n***********************<br/>" );
314
315 for( const REFDES_CHANGE& change : m_changeArray )
316 {
317 message += wxString::Format( wxT( "%s -> %s %s %s\n" ),
318 change.OldRefDesString,
319 change.NewRefDes,
320 ActionMessage[change.Action],
321 change.Action != UPDATE_REFDES ? _( "(will be ignored)" ) : wxString( "" ) );
322 }
323
324 ShowReport( message, RPT_SEVERITY_INFO );
325}
326
327
328void DIALOG_BOARD_REANNOTATE::LogFootprints( const wxString& aMessage,
329 const std::vector<REFDES_INFO>& aFootprints )
330{
331 wxString message = aMessage;
332
333 if( aFootprints.empty() )
334 message += _( "<br/>No footprints" );
335 else
336 {
337 int i = 1;
338
339 if( m_locationChoice->GetSelection() == 0 )
340 message += _( "<br/>*********** Sort on Footprint Coordinates ***********" );
341 else
342 message += _( "<br/>*********** Sort on Reference Coordinates ***********" );
343
344 for( const REFDES_INFO& fp : aFootprints )
345 {
346 message += wxString::Format( _( "<br/>%d %s X, Y: %s; rounded X, Y: %s" ),
347 i++,
348 fp.RefDesString,
349 CoordTowxString( fp.x, fp.y ),
350 CoordTowxString( fp.roundedx, fp.roundedy ) );
351 }
352 }
353
354 ShowReport( message, RPT_SEVERITY_INFO );
355}
356
357
359{
360 std::vector<REFDES_INFO> BadRefDes;
361 wxString message, badrefdes;
362 STRING_FORMATTER stringformatter;
363 REFDES_CHANGE* newref;
365
366 if( !BuildFootprintList( BadRefDes ) )
367 {
368 ShowReport( _( "Selected options resulted in errors! Change them and try again." ), RPT_SEVERITY_ERROR );
369 return false;
370 }
371
372 if( !BadRefDes.empty() )
373 {
374 message.Printf( _( "<br/>PCB has %d empty or invalid reference designations."
375 "<br/>Recommend running DRC with 'Test for parity between PCB and schematic' checked.\n" ),
376 (int) BadRefDes.size() );
377
378 for( const REFDES_INFO& mod : BadRefDes )
379 {
380 badrefdes += wxString::Format( _( "<br/>RefDes: %s Footprint: %s:%s at %s on PCB." ),
381 mod.RefDesString,
382 mod.FPID.GetLibNickname().wx_str(),
383 mod.FPID.GetLibItemName().wx_str(),
384 CoordTowxString( mod.x, mod.y ) );
385 }
386
387 ShowReport( message + badrefdes + wxT( "\n" ), RPT_SEVERITY_WARNING );
388 message += _( "Reannotate anyway?" );
389
390 if( !IsOK( m_frame, message ) )
391 return false;
392 }
393
394 BOARD_COMMIT commit( m_frame );
395
396 for( FOOTPRINT* footprint : m_footprints )
397 {
398 newref = GetNewRefDes( footprint );
399
400 if( nullptr == newref )
401 return false;
402
403 commit.Modify( footprint ); // Make a copy for undo
404 footprint->SetReference( newref->NewRefDes ); // Update the PCB reference
405 m_frame->GetCanvas()->GetView()->Update( footprint ); // Touch the footprint
406 }
407
408 commit.Push( _( "Annotation" ) );
409 return true;
410}
411
412
413bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<REFDES_INFO>& aBadRefDes )
414{
415 bool annotateSelected = m_AnnotateSelection->GetValue();
416 bool annotateFront = m_AnnotateFront->GetValue();
417 bool annotateBack = m_AnnotateBack->GetValue();
418 bool skipLocked = m_ExcludeLocked->GetValue();
419
420 GRID sortGridMils = m_frame->config()->m_Window.grid.grids[ m_GridChoice->GetSelection() ];
421 int sortGridx = (int) EDA_UNIT_UTILS::UI::ValueFromString( pcbIUScale, EDA_UNITS::MILS, sortGridMils.x );
422 int sortGridy = (int) EDA_UNIT_UTILS::UI::ValueFromString( pcbIUScale, EDA_UNITS::MILS, sortGridMils.y );
423
424 int errorcount = 0;
425 size_t firstnum = 0;
426
427 m_frontFootprints.clear();
428 m_backFootprints.clear();
429 m_excludeArray.clear();
431
432 wxStringTokenizer tokenizer( m_ExcludeList->GetValue(), wxS( " ," ), wxTOKEN_STRTOK );
433
434 while( tokenizer.HasMoreTokens() )
435 m_excludeArray.push_back( tokenizer.GetNextToken() );
436
437 REFDES_INFO fpData;
438 bool useFPLocation = m_locationChoice->GetSelection() == 0;
439
440 for( FOOTPRINT* footprint : m_footprints )
441 {
442 fpData.Uuid = footprint->m_Uuid;
443 fpData.RefDesString = footprint->GetReference();
444 fpData.FPID = footprint->GetFPID();
445 fpData.x = useFPLocation ? footprint->GetPosition().x
446 : footprint->Reference().GetPosition().x;
447 fpData.y = useFPLocation ? footprint->GetPosition().y
448 : footprint->Reference().GetPosition().y;
449 fpData.roundedx = RoundToGrid( fpData.x, sortGridx ); // Round to sort
450 fpData.roundedy = RoundToGrid( fpData.y, sortGridy );
451 fpData.Front = footprint->GetLayer() == F_Cu;
452 fpData.Action = UPDATE_REFDES; // Usually good
453
454 if( fpData.RefDesString.IsEmpty() )
455 {
456 fpData.Action = EMPTY_REFDES;
457 }
458 else
459 {
460 firstnum = fpData.RefDesString.find_first_of( wxT( "0123456789" ) );
461
462 if( std::string::npos == firstnum )
463 fpData.Action = INVALID_REFDES; // do not change ref des such as 12 or +1, or L
464 }
465
466 // Get the type (R, C, etc)
467 fpData.RefDesPrefix = fpData.RefDesString.substr( 0, firstnum );
468
469 for( const wxString& excluded : m_excludeArray )
470 {
471 if( excluded == fpData.RefDesPrefix ) // Am I supposed to exclude this type?
472 {
473 fpData.Action = EXCLUDE_REFDES; // Yes
474 break;
475 }
476 }
477
478 if( footprint->IsLocked() && skipLocked )
479 fpData.Action = EXCLUDE_REFDES;
480 else if( annotateSelected )
481 fpData.Action = footprint->IsSelected() ? UPDATE_REFDES : EXCLUDE_REFDES;
482 else if( annotateFront )
483 fpData.Action = fpData.Front ? UPDATE_REFDES : EXCLUDE_REFDES;
484 else if( annotateBack )
485 fpData.Action = fpData.Front ? EXCLUDE_REFDES : UPDATE_REFDES;
486
487 if( fpData.Front )
488 m_frontFootprints.push_back( fpData );
489 else
490 m_backFootprints.push_back( fpData );
491 }
492
493 int sortCode = 0; // Convert radio button to sort direction code
494
495 for( wxRadioButton* sortbuttons : m_sortButtons )
496 {
497 if( sortbuttons->GetValue() )
498 break;
499
500 sortCode++;
501 }
502
503 if( sortCode >= (int) m_sortButtons.size() )
504 sortCode = 0;
505
506 // Determine the sort order for the front.
508
509 // Sort the front footprints.
511
512 // Determine the sort order for the back.
514
515 // Sort the back footprints.
516 sort( m_backFootprints.begin(), m_backFootprints.end(), FootprintCompare );
517
518 m_refDesPrefixInfos.clear();
519 m_changeArray.clear();
520
522
523 if( !m_frontFootprints.empty() )
524 {
526 m_FrontPrefix->GetValue(), m_RemoveFrontPrefix->GetValue(), aBadRefDes );
527 }
528
529 if( !m_backFootprints.empty() )
530 {
532 m_BackPrefix->GetValue(), m_RemoveBackPrefix->GetValue(), aBadRefDes );
533 }
534
535 if( !m_changeArray.empty() )
536 sort( m_changeArray.begin(), m_changeArray.end(), ChangeArrayCompare );
537
539
540 size_t changearraysize = m_changeArray.size();
541
542 for( size_t i = 0; i < changearraysize; i++ ) // Scan through for duplicates if update or skip
543 {
544 if( m_changeArray[i].Action != EMPTY_REFDES && m_changeArray[i].Action != INVALID_REFDES )
545 {
546 for( size_t j = i + 1; j < changearraysize; j++ )
547 {
548 if( m_changeArray[i].NewRefDes == m_changeArray[j].NewRefDes )
549 {
550 ShowReport( wxString::Format( _( "Duplicate instances of %s" ), m_changeArray[j].NewRefDes ),
552
553 if( errorcount++ > MAXERROR )
554 {
555 ShowReport( _( "Aborted: too many errors" ), RPT_SEVERITY_ERROR );
556 break;
557 }
558 }
559 }
560 }
561
562 if( errorcount > MAXERROR )
563 break;
564 }
565
566 return ( errorcount == 0 );
567}
568
570{
571 std::vector<REFDES_INFO> excludedFootprints;
572
573 for( const REFDES_INFO& fpData : m_frontFootprints )
574 {
575 if( fpData.Action == EXCLUDE_REFDES )
576 excludedFootprints.push_back( fpData );
577 }
578
579 for( const REFDES_INFO& fpData : m_backFootprints )
580 {
581 if( fpData.Action == EXCLUDE_REFDES )
582 excludedFootprints.push_back( fpData );
583 }
584
585 for( const REFDES_INFO& fpData : excludedFootprints )
586 {
587 if( fpData.Action == EXCLUDE_REFDES )
588 {
589 REFDES_PREFIX_INFO* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesPrefix );
590 refDesInfo->UnavailableRefs.insert( UTIL::GetRefDesNumber( fpData.RefDesString ) );
591 }
592 }
593}
594
595
596void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<REFDES_INFO>& aFootprints,
597 unsigned int aStartRefDes, const wxString& aPrefix,
598 bool aRemovePrefix,
599 std::vector<REFDES_INFO>& aBadRefDes )
600{
601 size_t prefixsize = aPrefix.size();
602
603 bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix?
604 bool addprefix = haveprefix & !aRemovePrefix; // Yes- and I'm not removing it
605 aRemovePrefix &= haveprefix; // Only remove if I have a prefix
606
607 bool prefixpresent; // Prefix found
608
609 wxString logstring = ( aFootprints.front().Front ) ? _( "<br/><br/>Front Footprints" )
610 : _( "<br/><br/>Back Footprints" );
611 LogFootprints( logstring, aFootprints );
612
613 if( aStartRefDes != 0 ) // Initialize the change array if present
614 {
615 for( size_t i = 0; i < m_refDesPrefixInfos.size(); i++ )
616 m_refDesPrefixInfos[i].LastUsedRefDes = aStartRefDes - 1;
617 }
618
619 for( REFDES_INFO fpData : aFootprints )
620 {
621 REFDES_CHANGE change;
622
623 change.Uuid = fpData.Uuid;
624 change.Action = fpData.Action;
625 change.OldRefDesString = fpData.RefDesString;
626 change.NewRefDes = fpData.RefDesString;
627 change.Front = fpData.Front;
628
629 if( fpData.RefDesString.IsEmpty() )
630 fpData.Action = EMPTY_REFDES;
631
632 if( ( change.Action == EMPTY_REFDES ) || ( change.Action == INVALID_REFDES ) )
633 {
634 m_changeArray.push_back( change );
635 aBadRefDes.push_back( fpData );
636 continue;
637 }
638
639 if( change.Action == UPDATE_REFDES )
640 {
641 prefixpresent = ( fpData.RefDesPrefix.find( aPrefix ) == 0 );
642
643 if( addprefix && !prefixpresent )
644 fpData.RefDesPrefix.insert( 0, aPrefix ); // Add prefix once only
645
646 if( aRemovePrefix && prefixpresent ) // If there is a prefix remove it
647 fpData.RefDesPrefix.erase( 0, prefixsize );
648
649 REFDES_PREFIX_INFO* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesPrefix, aStartRefDes );
650 unsigned int newRefDesNumber = refDesInfo->LastUsedRefDes + 1;
651
652 while( refDesInfo->UnavailableRefs.count( newRefDesNumber ) )
653 newRefDesNumber++;
654
655 change.NewRefDes = refDesInfo->RefDesPrefix + std::to_string( newRefDesNumber );
656 refDesInfo->LastUsedRefDes = newRefDesNumber;
657 }
658
659 m_changeArray.push_back( change );
660 }
661}
662
663
665{
666 size_t i;
667
668 for( i = 0; i < m_changeArray.size(); i++ )
669 {
670 if( aFootprint->m_Uuid == m_changeArray[i].Uuid )
671 return ( &m_changeArray[i] );
672 }
673
674 ShowReport( _( "Footprint not found in changelist" ) + wxS( " " ) + aFootprint->GetReference(),
676
677 return nullptr; // Should never happen
678}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
WINDOW_SETTINGS m_Window
Definition: app_settings.h:233
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
const FOOTPRINTS & Footprints() const
Definition: board.h:358
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
Class DIALOG_BOARD_REANNOTATE_BASE.
std::vector< REFDES_CHANGE > m_changeArray
std::vector< wxString > m_excludeArray
bool BuildFootprintList(std::vector< REFDES_INFO > &aBadRefDes)
Build the footprint lists, sort it, filter for excludes, then build the change list.
void FilterBackPrefix(wxCommandEvent &event) override
void LogFootprints(const wxString &aMessage, const std::vector< REFDES_INFO > &aFootprints)
Create a list of the footprints and their coordinates.
std::vector< REFDES_INFO > m_frontFootprints
wxString CoordTowxString(int aX, int aY)
Convert coordinates to wxString.
void FilterPrefix(wxTextCtrl *aPrefix)
Check to make sure the prefix (if there is one) is properly constructed.
void BuildChangeArray(std::vector< REFDES_INFO > &aFootprints, unsigned int aStartRefDes, const wxString &aPrefix, bool aRemovePrefix, std::vector< REFDES_INFO > &aBadRefDes)
Scan through the footprint arrays and create the from -> to array.
int RoundToGrid(int aCoord, int aGrid)
Round an int coordinate to a suitable grid.
REFDES_PREFIX_INFO * GetOrBuildRefDesInfo(const wxString &aRefDesPrefix, int aStartRefDes=1)
Get the structure representing the information currently held for aRefDesPrefix or create one if it d...
void BuildUnavailableRefsList()
Build list of unavailable references. E.g. unselected footprints or locked footprints.
void LogChangePlan(void)
Create an audit trail of the changes.
void OnCloseClick(wxCommandEvent &event) override
REFDES_CHANGE * GetNewRefDes(FOOTPRINT *aFootprint)
bool ReannotateBoard(void)
Actually reannotate the board.
void ShowReport(const wxString &aMessage, SEVERITY aSeverity)
Break report into strings separated by and sent to the reporter.
std::vector< REFDES_INFO > m_backFootprints
std::vector< REFDES_PREFIX_INFO > m_refDesPrefixInfos
DIALOG_BOARD_REANNOTATE(PCB_EDIT_FRAME *aParentFrame)
void OnApplyClick(wxCommandEvent &event) override
std::vector< wxRadioButton * > m_sortButtons
void FilterFrontPrefix(wxCommandEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
const KIID m_Uuid
Definition: eda_item.h:516
const wxString & GetReference() const
Definition: footprint.h:627
static void BuildChoiceList(wxArrayString *aGridsList, APP_SETTINGS_BASE *aCfg, EDA_DRAW_FRAME *aParent)
Definition: grid_menu.cpp:83
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:91
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition: pcb_netlist.h:274
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
The main frame for Pcbnew.
void OnModify() override
Must be called after a board change to set the modified flag.
The selection tool: currently supports:
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:115
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:449
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void SetLazyUpdate(bool aLazyUpdate)
Set the lazy update.
void SetFileName(const wxString &aReportFileName)
Set the report full file name to the string.
void Report(const wxString &aText, SEVERITY aSeverity, REPORTER::LOCATION aLocation=REPORTER::LOC_BODY)
Report the string.
void Flush(bool aSort=false)
Force updating the HTML page, after the report is built in lazy mode If aSort = true,...
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:251
This file is part of the common library.
int BackDirectionsArray[]
int FrontDirectionsArray[]
bool g_DescendingFirst
bool g_DescendingSecond
#define SetSortCodes(DirArray, Code)
bool g_SortYFirst
static bool ChangeArrayCompare(const REFDES_CHANGE &aA, const REFDES_CHANGE &aB)
Compare function used to compare ChangeArray element for sort.
static bool FootprintCompare(const REFDES_INFO &aA, const REFDES_INFO &aB)
Compare function to sort footprints.
wxString ActionMessage[]
#define MAXERROR
#define DESCENDINGFIRST
#define SORTXFIRST
@ INVALID_REFDES
@ EXCLUDE_REFDES
#define DESCENDINGSECOND
#define ASCENDINGFIRST
#define SORTYFIRST
#define ASCENDINGSECOND
#define MINGRID
#define VALIDPREFIX
#define _(s)
@ F_Cu
Definition: layer_ids.h:64
KICOMMON_API long long int ValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue in aUnits to internal units used by the application.
Definition: eda_units.cpp:689
int GetRefDesNumber(const wxString &aRefDes)
Get the numeric suffix from a refdes - e.g.
BOARD * GetBoard()
Collection of utility functions for component reference designators (refdes)
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
std::vector< GRID > grids
Definition: grid_settings.h:66
Common grid settings, available to every frame.
Definition: grid_settings.h:34
wxString y
Definition: grid_settings.h:53
wxString x
Definition: grid_settings.h:52
std::set< unsigned int > UnavailableRefs
GRID_SETTINGS grid
Definition: app_settings.h:97