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
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 int gridIndex = m_frame->config()->m_Window.grid.last_size_idx;
122
123 if( gridIndex >= 0 && gridIndex < (int) m_GridChoice->GetCount() )
124 m_GridChoice->SetSelection( gridIndex );
125 else
126 m_GridChoice->SetSelection( 0 );
127
128 m_ExcludeList->SetToolTip( m_ExcludeListText->GetToolTipText() );
129 m_GridChoice->SetToolTip( m_SortGridText->GetToolTipText() );
130
131 m_MessageWindow->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
132
134}
135
136
137void DIALOG_BOARD_REANNOTATE::OnCloseClick( wxCommandEvent& event )
138{
139 EndDialog( wxID_OK );
140}
141
142
144{
145 PCB_SELECTION selection = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
146
147 if( !selection.Empty() )
148 m_AnnotateSelection->SetValue( true );
149
150 // Ensure m_GridChoice selection validity
151 // If not, the choice 0 is arbitrary
152 if( m_GridChoice->GetSelection() < 0 || m_GridChoice->GetSelection() >= (int)m_GridChoice->GetCount() )
153 m_GridChoice->SetSelection( 0 );
154
155 return true;
156}
157
158
159void DIALOG_BOARD_REANNOTATE::FilterPrefix( wxTextCtrl* aPrefix )
160{
161 std::string tmps = VALIDPREFIX;
162
163 if( aPrefix->GetValue().empty() )
164 return; //Should never happen
165
166 char lastc = aPrefix->GetValue().Last();
167
168 if( isalnum( (int) lastc ) )
169 return;
170
171 if( tmps.find( lastc ) != std::string::npos )
172 return;
173
174 tmps = aPrefix->GetValue();
175 aPrefix->Clear();
176 tmps.pop_back();
177 aPrefix->AppendText( tmps );
178}
179
180
182 int aStartRefDes )
183{
184 for( size_t i = 0; i < m_refDesPrefixInfos.size(); i++ ) // See if it is in the info array
185 {
186 if( m_refDesPrefixInfos[i].RefDesPrefix == aRefDesPrefix ) // Found it!
187 return &m_refDesPrefixInfos[i];
188 }
189
190 // Wasn't in the info array so add it
191 REFDES_PREFIX_INFO newtype;
192 newtype.RefDesPrefix = aRefDesPrefix;
193 newtype.LastUsedRefDes = aStartRefDes - 1;
194 m_refDesPrefixInfos.push_back( newtype );
195
196 return &m_refDesPrefixInfos.back();
197}
198
199
201{
203}
204
205
206void DIALOG_BOARD_REANNOTATE::FilterBackPrefix( wxCommandEvent& event )
207{
209}
210
211
212void DIALOG_BOARD_REANNOTATE::OnApplyClick( wxCommandEvent& event )
213{
214 m_MessageWindow->SetLazyUpdate( true );
215
216 if( ReannotateBoard() )
217 {
218 ShowReport( _( "PCB successfully reannotated" ), RPT_SEVERITY_ACTION );
219 ShowReport( _( "PCB annotation changes should be synchronized with schematic using "
220 "the \"Update Schematic from PCB\" tool." ), RPT_SEVERITY_WARNING );
221 }
222
223 m_MessageWindow->SetLazyUpdate( false );
224 m_MessageWindow->Flush( false );
225 m_frame->GetCanvas()->Refresh(); // Redraw
226 m_frame->OnModify(); // Need to save file on exit.
227}
228
229
230int DIALOG_BOARD_REANNOTATE::RoundToGrid( int aCoord, int aGrid )
231{
232 if( 0 == aGrid )
233 aGrid = MINGRID;
234
235 int rounder;
236 rounder = aCoord % aGrid;
237 aCoord -= rounder;
238
239 if( abs( rounder ) > ( aGrid / 2 ) )
240 aCoord += ( aCoord < 0 ? -aGrid : aGrid );
241
242 return ( aCoord );
243}
244
245
248static bool ChangeArrayCompare( const REFDES_CHANGE& aA, const REFDES_CHANGE& aB )
249{
250 return ( StrNumCmp( aA.OldRefDesString, aB.OldRefDesString ) < 0 );
251}
252
253
256static bool FootprintCompare( const REFDES_INFO& aA, const REFDES_INFO& aB )
257{
258 int X0 = aA.roundedx, X1 = aB.roundedx, Y0 = aA.roundedy, Y1 = aB.roundedy;
259
260 if( g_SortYFirst ) //If sorting by Y then X, swap X and Y
261 {
262 std::swap( X0, Y0 );
263 std::swap( X1, Y1 );
264 }
265
266 // If descending, same compare just swap directions
268 std::swap( X0, X1 );
269
271 std::swap( Y0, Y1 );
272
273 if( X0 < X1 )
274 return true; // yes, it's smaller
275 else if( X0 > X1 )
276 return false; // no, it's not
277 else if( Y0 < Y1 )
278 return true;
279 else
280 return false;
281}
282
283
285{
286 return wxString::Format( wxT( "%s, %s" ),
287 m_frame->MessageTextFromValue( aX ),
288 m_frame->MessageTextFromValue( aY ) );
289}
290
291
292void DIALOG_BOARD_REANNOTATE::ShowReport( const wxString& aMessage, SEVERITY aSeverity )
293{
294 wxStringTokenizer msgs( aMessage, "\n" );
295
296 while( msgs.HasMoreTokens() )
297 m_MessageWindow->Report( msgs.GetNextToken(), aSeverity );
298}
299
300
302{
303 int i = 1;
304 wxString message;
305
306 message.Printf( _( "<br/>There are %i reference designator prefixes in use<br/>"
307 "**********************************************************<br/>" ),
308 (int) m_refDesPrefixInfos.size() );
309
310 for( const REFDES_PREFIX_INFO& info : m_refDesPrefixInfos ) // Show all the types of refdes
311 message += info.RefDesPrefix + ( ( i++ % 16 ) == 0 ? wxT( "<br/>" ) : wxS( " " ) );
312
313 message += wxT( "<br/>" );
314
315 if( !m_excludeArray.empty() )
316 {
317 wxString excludes;
318
319 for( wxString& exclude : m_excludeArray ) // Show the refdes we are excluding
320 excludes += exclude + wxS( " " );
321
322 message += wxString::Format( _( "Excluding: %s from reannotation<br/>" ), excludes );
323 }
324
325 message += _( "<br/>Change Array\n***********************<br/>" );
326
327 for( const REFDES_CHANGE& change : m_changeArray )
328 {
329 message += wxString::Format( wxT( "%s -> %s %s %s\n" ),
330 change.OldRefDesString,
331 change.NewRefDes,
332 ActionMessage[change.Action],
333 change.Action != UPDATE_REFDES ? _( "(will be ignored)" ) : wxString( "" ) );
334 }
335
336 ShowReport( message, RPT_SEVERITY_INFO );
337}
338
339
340void DIALOG_BOARD_REANNOTATE::LogFootprints( const wxString& aMessage,
341 const std::vector<REFDES_INFO>& aFootprints )
342{
343 wxString message = aMessage;
344
345 if( aFootprints.empty() )
346 message += _( "<br/>No footprints" );
347 else
348 {
349 int i = 1;
350
351 if( m_locationChoice->GetSelection() == 0 )
352 message += _( "<br/>*********** Sort on Footprint Coordinates ***********" );
353 else
354 message += _( "<br/>*********** Sort on Reference Coordinates ***********" );
355
356 for( const REFDES_INFO& fp : aFootprints )
357 {
358 message += wxString::Format( _( "<br/>%d %s X, Y: %s; rounded X, Y: %s" ),
359 i++,
360 fp.RefDesString,
361 CoordTowxString( fp.x, fp.y ),
362 CoordTowxString( fp.roundedx, fp.roundedy ) );
363 }
364 }
365
366 ShowReport( message, RPT_SEVERITY_INFO );
367}
368
369
371{
372 std::vector<REFDES_INFO> BadRefDes;
373 wxString message, badrefdes;
374 STRING_FORMATTER stringformatter;
375 REFDES_CHANGE* newref;
377
378 if( !BuildFootprintList( BadRefDes ) )
379 {
380 ShowReport( _( "Selected options resulted in errors! Change them and try again." ), RPT_SEVERITY_ERROR );
381 return false;
382 }
383
384 if( !BadRefDes.empty() )
385 {
386 message.Printf( _( "<br/>PCB has %d empty or invalid reference designations."
387 "<br/>Recommend running DRC with 'Test for parity between PCB and schematic' checked.\n" ),
388 (int) BadRefDes.size() );
389
390 for( const REFDES_INFO& mod : BadRefDes )
391 {
392 badrefdes += wxString::Format( _( "<br/>RefDes: %s Footprint: %s:%s at %s on PCB." ),
393 mod.RefDesString,
394 mod.FPID.GetLibNickname().wx_str(),
395 mod.FPID.GetLibItemName().wx_str(),
396 CoordTowxString( mod.x, mod.y ) );
397 }
398
399 ShowReport( message + badrefdes + wxT( "\n" ), RPT_SEVERITY_WARNING );
400 message += _( "Reannotate anyway?" );
401
402 if( !IsOK( m_frame, message ) )
403 return false;
404 }
405
406 BOARD_COMMIT commit( m_frame );
407
408 for( FOOTPRINT* footprint : m_footprints )
409 {
410 newref = GetNewRefDes( footprint );
411
412 if( nullptr == newref )
413 return false;
414
415 commit.Modify( footprint ); // Make a copy for undo
416 footprint->SetReference( newref->NewRefDes ); // Update the PCB reference
417 m_frame->GetCanvas()->GetView()->Update( footprint ); // Touch the footprint
418 }
419
420 commit.Push( _( "Annotation" ) );
421 return true;
422}
423
424
425bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector<REFDES_INFO>& aBadRefDes )
426{
427 bool annotateSelected = m_AnnotateSelection->GetValue();
428 bool annotateFront = m_AnnotateFront->GetValue();
429 bool annotateBack = m_AnnotateBack->GetValue();
430 bool skipLocked = m_ExcludeLocked->GetValue();
431
432 GRID sortGridMils = m_frame->config()->m_Window.grid.grids[ m_GridChoice->GetSelection() ];
433 int sortGridx = (int) EDA_UNIT_UTILS::UI::ValueFromString( pcbIUScale, EDA_UNITS::MILS, sortGridMils.x );
434 int sortGridy = (int) EDA_UNIT_UTILS::UI::ValueFromString( pcbIUScale, EDA_UNITS::MILS, sortGridMils.y );
435
436 int errorcount = 0;
437 size_t firstnum = 0;
438
439 m_frontFootprints.clear();
440 m_backFootprints.clear();
441 m_excludeArray.clear();
442 m_footprints = m_frame->GetBoard()->Footprints();
443
444 wxStringTokenizer tokenizer( m_ExcludeList->GetValue(), " ,", wxTOKEN_STRTOK );
445
446 while( tokenizer.HasMoreTokens() )
447 m_excludeArray.push_back( tokenizer.GetNextToken() );
448
449 REFDES_INFO fpData;
450 bool useFPLocation = m_locationChoice->GetSelection() == 0;
451
452 for( FOOTPRINT* footprint : m_footprints )
453 {
454 fpData.Uuid = footprint->m_Uuid;
455 fpData.RefDesString = footprint->GetReference();
456 fpData.FPID = footprint->GetFPID();
457 fpData.x = useFPLocation ? footprint->GetPosition().x
458 : footprint->Reference().GetPosition().x;
459 fpData.y = useFPLocation ? footprint->GetPosition().y
460 : footprint->Reference().GetPosition().y;
461 fpData.roundedx = RoundToGrid( fpData.x, sortGridx ); // Round to sort
462 fpData.roundedy = RoundToGrid( fpData.y, sortGridy );
463 fpData.Front = footprint->GetLayer() == F_Cu;
464 fpData.Action = UPDATE_REFDES; // Usually good
465
466 if( fpData.RefDesString.IsEmpty() )
467 {
468 fpData.Action = EMPTY_REFDES;
469 }
470 else
471 {
472 firstnum = fpData.RefDesString.find_first_of( wxT( "0123456789" ) );
473
474 if( std::string::npos == firstnum )
475 fpData.Action = INVALID_REFDES; // do not change ref des such as 12 or +1, or L
476 }
477
478 // Get the type (R, C, etc)
479 fpData.RefDesPrefix = fpData.RefDesString.substr( 0, firstnum );
480
481 for( const wxString& excluded : m_excludeArray )
482 {
483 if( excluded == fpData.RefDesPrefix ) // Am I supposed to exclude this type?
484 {
485 fpData.Action = EXCLUDE_REFDES; // Yes
486 break;
487 }
488 }
489
490 if( footprint->IsLocked() && skipLocked )
491 fpData.Action = EXCLUDE_REFDES;
492 else if( annotateSelected )
493 fpData.Action = footprint->IsSelected() ? UPDATE_REFDES : EXCLUDE_REFDES;
494 else if( annotateFront )
495 fpData.Action = fpData.Front ? UPDATE_REFDES : EXCLUDE_REFDES;
496 else if( annotateBack )
497 fpData.Action = fpData.Front ? EXCLUDE_REFDES : UPDATE_REFDES;
498
499 if( fpData.Front )
500 m_frontFootprints.push_back( fpData );
501 else
502 m_backFootprints.push_back( fpData );
503 }
504
505 int sortCode = 0; // Convert radio button to sort direction code
506
507 for( wxRadioButton* sortbuttons : m_sortButtons )
508 {
509 if( sortbuttons->GetValue() )
510 break;
511
512 sortCode++;
513 }
514
515 if( sortCode >= (int) m_sortButtons.size() )
516 sortCode = 0;
517
518 // Determine the sort order for the front.
520
521 // Sort the front footprints.
523
524 // Determine the sort order for the back.
526
527 // Sort the back footprints.
528 sort( m_backFootprints.begin(), m_backFootprints.end(), FootprintCompare );
529
530 m_refDesPrefixInfos.clear();
531 m_changeArray.clear();
532
534
535 if( !m_frontFootprints.empty() )
536 {
538 m_FrontPrefix->GetValue(), m_RemoveFrontPrefix->GetValue(), aBadRefDes );
539 }
540
541 if( !m_backFootprints.empty() )
542 {
544 m_BackPrefix->GetValue(), m_RemoveBackPrefix->GetValue(), aBadRefDes );
545 }
546
547 if( !m_changeArray.empty() )
548 sort( m_changeArray.begin(), m_changeArray.end(), ChangeArrayCompare );
549
551
552 size_t changearraysize = m_changeArray.size();
553
554 for( size_t i = 0; i < changearraysize; i++ ) // Scan through for duplicates if update or skip
555 {
556 if( m_changeArray[i].Action != EMPTY_REFDES && m_changeArray[i].Action != INVALID_REFDES )
557 {
558 for( size_t j = i + 1; j < changearraysize; j++ )
559 {
560 if( m_changeArray[i].NewRefDes == m_changeArray[j].NewRefDes )
561 {
562 ShowReport( wxString::Format( _( "Duplicate instances of %s" ), m_changeArray[j].NewRefDes ),
564
565 if( errorcount++ > MAXERROR )
566 {
567 ShowReport( _( "Aborted: too many errors" ), RPT_SEVERITY_ERROR );
568 break;
569 }
570 }
571 }
572 }
573
574 if( errorcount > MAXERROR )
575 break;
576 }
577
578 return ( errorcount == 0 );
579}
580
582{
583 std::vector<REFDES_INFO> excludedFootprints;
584
585 for( const REFDES_INFO& fpData : m_frontFootprints )
586 {
587 if( fpData.Action == EXCLUDE_REFDES )
588 excludedFootprints.push_back( fpData );
589 }
590
591 for( const REFDES_INFO& fpData : m_backFootprints )
592 {
593 if( fpData.Action == EXCLUDE_REFDES )
594 excludedFootprints.push_back( fpData );
595 }
596
597 for( const REFDES_INFO& fpData : excludedFootprints )
598 {
599 if( fpData.Action == EXCLUDE_REFDES )
600 {
601 REFDES_PREFIX_INFO* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesPrefix );
602 refDesInfo->UnavailableRefs.insert( UTIL::GetRefDesNumber( fpData.RefDesString ) );
603 }
604 }
605}
606
607
608void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector<REFDES_INFO>& aFootprints,
609 unsigned int aStartRefDes, const wxString& aPrefix,
610 bool aRemovePrefix,
611 std::vector<REFDES_INFO>& aBadRefDes )
612{
613 size_t prefixsize = aPrefix.size();
614
615 bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix?
616 bool addprefix = haveprefix & !aRemovePrefix; // Yes- and I'm not removing it
617 aRemovePrefix &= haveprefix; // Only remove if I have a prefix
618
619 bool prefixpresent; // Prefix found
620
621 wxString logstring = ( aFootprints.front().Front ) ? _( "<br/><br/>Front Footprints" )
622 : _( "<br/><br/>Back Footprints" );
623 LogFootprints( logstring, aFootprints );
624
625 if( aStartRefDes != 0 ) // Initialize the change array if present
626 {
627 for( size_t i = 0; i < m_refDesPrefixInfos.size(); i++ )
628 m_refDesPrefixInfos[i].LastUsedRefDes = aStartRefDes - 1;
629 }
630
631 for( REFDES_INFO fpData : aFootprints )
632 {
633 REFDES_CHANGE change;
634
635 change.Uuid = fpData.Uuid;
636 change.Action = fpData.Action;
637 change.OldRefDesString = fpData.RefDesString;
638 change.NewRefDes = fpData.RefDesString;
639 change.Front = fpData.Front;
640
641 if( fpData.RefDesString.IsEmpty() )
642 fpData.Action = EMPTY_REFDES;
643
644 if( ( change.Action == EMPTY_REFDES ) || ( change.Action == INVALID_REFDES ) )
645 {
646 m_changeArray.push_back( change );
647 aBadRefDes.push_back( fpData );
648 continue;
649 }
650
651 if( change.Action == UPDATE_REFDES )
652 {
653 prefixpresent = ( fpData.RefDesPrefix.find( aPrefix ) == 0 );
654
655 if( addprefix && !prefixpresent )
656 fpData.RefDesPrefix.insert( 0, aPrefix ); // Add prefix once only
657
658 if( aRemovePrefix && prefixpresent ) // If there is a prefix remove it
659 fpData.RefDesPrefix.erase( 0, prefixsize );
660
661 REFDES_PREFIX_INFO* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesPrefix, aStartRefDes );
662 unsigned int newRefDesNumber = refDesInfo->LastUsedRefDes + 1;
663
664 while( refDesInfo->UnavailableRefs.count( newRefDesNumber ) )
665 newRefDesNumber++;
666
667 change.NewRefDes = refDesInfo->RefDesPrefix + std::to_string( newRefDesNumber );
668 refDesInfo->LastUsedRefDes = newRefDesNumber;
669 }
670
671 m_changeArray.push_back( change );
672 }
673}
674
675
677{
678 size_t i;
679
680 for( i = 0; i < m_changeArray.size(); i++ )
681 {
682 if( aFootprint->m_Uuid == m_changeArray[i].Uuid )
683 return ( &m_changeArray[i] );
684 }
685
686 ShowReport( _( "Footprint not found in changelist" ) + wxS( " " ) + aFootprint->GetReference(),
688
689 return nullptr; // Should never happen
690}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
@ reannotate_down_left
@ reannotate_up_right
@ reannotate_right_down
@ reannotate_up_left
@ reannotate_left_down
@ reannotate_down_right
@ reannotate_left_up
@ reannotate_right_up
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
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:106
DIALOG_BOARD_REANNOTATE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Geographical Reannotation"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
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...
const KIID m_Uuid
Definition eda_item.h:516
const wxString & GetReference() const
Definition footprint.h:661
static void BuildChoiceList(wxArrayString *aGridsList, APP_SETTINGS_BASE *aCfg, EDA_DRAW_FRAME *aParent)
Definition grid_menu.cpp:83
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.
The main frame for Pcbnew.
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
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
#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.
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.
Common grid settings, available to every frame.
wxString y
wxString x
std::set< unsigned int > UnavailableRefs