KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_sheet.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2023 CERN
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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
22#include <cstdlib>
23
24#include <bitmaps.h>
25#include <core/mirror.h>
26#include <core/kicad_algo.h>
27#include <sch_draw_panel.h>
28#include <trigo.h>
29#include <sch_edit_frame.h>
30#include <plotters/plotter.h>
31#include <sch_plotter.h>
32#include <string_utils.h>
33#include <widgets/msgpanel.h>
34#include <math/util.h> // for KiROUND
36#include <api/api_enums.h>
37#include <api/api_utils.h>
38#include <api/schematic/schematic_types.pb.h>
39#include <sch_sheet.h>
40#include <sch_sheet_path.h>
41#include <sch_sheet_pin.h>
42#include <sch_no_connect.h>
43#include <sch_symbol.h>
44#include <sch_painter.h>
45#include <schematic.h>
47#include <trace_helpers.h>
48#include <validators.h>
50#include <properties/property.h>
52#include <pgm_base.h>
53#include <wx/log.h>
54
80
81
82void SCH_SHEET::Serialize( google::protobuf::Any& aContainer ) const
83{
84 using namespace kiapi::common;
85 using namespace kiapi::common::types;
86 using namespace kiapi::schematic::types;
87
88 SheetSymbol sheet;
89
90 sheet.mutable_id()->set_value( m_Uuid.AsStdString() );
91 PackVector2( *sheet.mutable_position(), GetPosition(), schIUScale );
92 PackVector2( *sheet.mutable_size(), GetSize(), schIUScale );
93 sheet.set_locked( IsLocked() ? LockedState::LS_LOCKED : LockedState::LS_UNLOCKED );
94 sheet.set_exclude_from_sim( GetExcludedFromSim() );
95 sheet.set_exclude_from_bom( GetExcludedFromBOM() );
96 sheet.set_exclude_from_board( GetExcludedFromBoard() );
97 sheet.set_dnp( GetDNP() );
98
99 StrokeAttributes* borderStroke = sheet.mutable_border_stroke();
100 PackDistance( *borderStroke->mutable_width(), GetBorderWidth(), schIUScale );
102
104 PackColor( *borderStroke->mutable_color(), GetBorderColor() );
105
106 GraphicFillAttributes* fill = sheet.mutable_fill();
107 fill->set_fill_type( GetBackgroundColor() == COLOR4D::UNSPECIFIED ? GraphicFillType::GFT_UNFILLED
108 : GraphicFillType::GFT_FILLED_WITH_COLOR );
109
111 PackColor( *fill->mutable_color(), GetBackgroundColor() );
112
113 google::protobuf::Any any;
114
116 any.UnpackTo( sheet.mutable_name_field() );
117
119 any.UnpackTo( sheet.mutable_filename_field() );
120
121 for( const SCH_FIELD& field : GetFields() )
122 {
123 if( field.IsMandatory() )
124 continue;
125
126 field.Serialize( any );
127 any.UnpackTo( sheet.add_user_fields() );
128 }
129
130 for( const SCH_SHEET_PIN* pin : GetPins() )
131 {
132 pin->Serialize( any );
133 any.UnpackTo( sheet.add_pins() );
134 }
135
136 aContainer.PackFrom( sheet );
137}
138
139
140bool SCH_SHEET::Deserialize( const google::protobuf::Any& aContainer )
141{
142 using namespace kiapi::common;
143 using namespace kiapi::common::types;
144 using namespace kiapi::schematic::types;
145
146 SheetSymbol sheet;
147
148 if( !aContainer.UnpackTo( &sheet ) )
149 return false;
150
151 const_cast<::KIID&>( m_Uuid ) = ::KIID( sheet.id().value() );
152 SetPosition( UnpackVector2( sheet.position(), schIUScale ) );
153 SetSize( UnpackVector2( sheet.size(), schIUScale ) );
154 SetLocked( sheet.locked() == LockedState::LS_LOCKED );
155 SetExcludedFromSim( sheet.exclude_from_sim() );
156 SetExcludedFromBOM( sheet.exclude_from_bom() );
157 SetExcludedFromBoard( sheet.exclude_from_board() );
158 SetDNP( sheet.dnp() );
159
160 SetBorderWidth( UnpackDistance( sheet.border_stroke().width(), schIUScale ) );
161 SetBorderColor( sheet.border_stroke().has_color() ? UnpackColor( sheet.border_stroke().color() )
163
164 if( sheet.fill().fill_type() == GraphicFillType::GFT_UNFILLED || !sheet.fill().has_color() )
166 else
167 SetBackgroundColor( UnpackColor( sheet.fill().color() ) );
168
169 for( SCH_SHEET_PIN* pin : m_pins )
170 delete pin;
171
172 m_pins.clear();
173
174 m_fields.clear();
175 m_fields.emplace_back( this, FIELD_T::SHEET_NAME,
177 m_fields.emplace_back( this, FIELD_T::SHEET_FILENAME,
179
180 google::protobuf::Any any;
181
182 any.PackFrom( sheet.name_field() );
184
185 any.PackFrom( sheet.filename_field() );
187
188 for( const auto& field : sheet.user_fields() )
189 {
190 m_fields.emplace_back( this, FIELD_T::SHEET_USER );
191
192 any.PackFrom( field );
193 m_fields.back().Deserialize( any );
194 }
195
196 for( const auto& pinProto : sheet.pins() )
197 {
198 auto pin = std::make_unique<SCH_SHEET_PIN>( this );
199 any.PackFrom( pinProto );
200
201 if( !pin->Deserialize( any ) )
202 return false;
203
204 AddPin( pin.release() );
205 }
206
207 SetScreen( nullptr );
208
209 return true;
210}
211
212
214 SCH_ITEM( aSheet )
215{
216 m_pos = aSheet.m_pos;
217 m_size = aSheet.m_size;
218 m_layer = aSheet.m_layer;
219 const_cast<KIID&>( m_Uuid ) = aSheet.m_Uuid;
220 m_fields = aSheet.m_fields;
222 m_screen = aSheet.m_screen;
223
227 m_DNP = aSheet.m_DNP;
228
232 m_instances = aSheet.m_instances;
233
234 for( SCH_SHEET_PIN* pin : aSheet.m_pins )
235 {
236 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
237 m_pins.back()->SetParent( this );
238 }
239
240 for( SCH_FIELD& field : m_fields )
241 field.SetParent( this );
242
243 if( m_screen )
244 m_screen->IncRefCount();
245}
246
247
249{
250 // also, look at the associated sheet & its reference count
251 // perhaps it should be deleted also.
252 if( m_screen )
253 {
254 m_screen->DecRefCount();
255
256 if( m_screen->GetRefCount() == 0 )
257 delete m_screen;
258 }
259
260 // We own our pins; delete them
261 for( SCH_SHEET_PIN* pin : m_pins )
262 delete pin;
263}
264
265
267{
268 return new SCH_SHEET( *this );
269}
270
271
273{
274 if( aScreen == m_screen )
275 return;
276
277 if( m_screen != nullptr )
278 {
279 m_screen->DecRefCount();
280
281 if( m_screen->GetRefCount() == 0 )
282 {
283 delete m_screen;
284 m_screen = nullptr;
285 }
286 }
287
288 m_screen = aScreen;
289
290 if( m_screen )
291 m_screen->IncRefCount();
292}
293
294
296{
297 if( m_screen == nullptr )
298 return 0;
299
300 return m_screen->GetRefCount();
301}
302
303
305{
306 wxCHECK_MSG( Schematic(), false, "Can't call IsVirtualRootSheet without setting a schematic" );
307
308 return m_Uuid == niluuid;
309}
310
311
313{
314 wxCHECK_MSG( Schematic(), false, "Can't call IsTopLevelSheet without setting a schematic" );
315
316 return Schematic()->IsTopLevelSheet( this );
317}
318
319
320void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
321{
322 auto add =
323 [&]( const wxString& aVar )
324 {
325 if( !alg::contains( *aVars, aVar ) )
326 aVars->push_back( aVar );
327 };
328
329 for( const SCH_FIELD& field : m_fields )
330 {
331 if( field.IsMandatory() )
332 add( field.GetCanonicalName().Upper() );
333 else
334 add( field.GetName() );
335 }
336
337 SCH_SHEET_PATH sheetPath = findSelf();
338
339 if( sheetPath.size() >= 2 )
340 {
341 sheetPath.pop_back();
342 sheetPath.Last()->GetContextualTextVars( aVars );
343 }
344 else if( Schematic() )
345 {
347 }
348
349 add( wxT( "#" ) );
350 add( wxT( "##" ) );
351 add( wxT( "SHEETPATH" ) );
352 add( wxT( "EXCLUDE_FROM_BOM" ) );
353 add( wxT( "EXCLUDE_FROM_BOARD" ) );
354 add( wxT( "EXCLUDE_FROM_SIM" ) );
355 add( wxT( "DNP" ) );
356 add( wxT( "ERC_ERROR <message_text>" ) );
357 add( wxT( "ERC_WARNING <message_text>" ) );
358
359 m_screen->GetTitleBlock().GetContextualTextVars( aVars );
360}
361
362
363bool SCH_SHEET::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
364{
365 wxCHECK( aPath, false );
366
367 SCHEMATIC* schematic = Schematic();
368
369 if( !schematic )
370 return false;
371
372 if( token->Contains( ':' ) )
373 {
374 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
375 return true;
376 }
377
378 for( const SCH_FIELD& field : m_fields )
379 {
380 wxString fieldName = field.IsMandatory() ? field.GetCanonicalName().Upper()
381 : field.GetName();
382
383 if( token->IsSameAs( fieldName ) )
384 {
385 *token = field.GetShownText( aPath, false, aDepth + 1 );
386 return true;
387 }
388 }
389
390 PROJECT* project = &schematic->Project();
391 wxString variant = schematic->GetCurrentVariant();
392
393 // We cannot resolve text variables initially on load as we need to first load the screen and
394 // then parse the hierarchy. So skip the resolution if the screen isn't set yet
395 if( m_screen && m_screen->GetTitleBlock().TextVarResolver( token, project ) )
396 {
397 return true;
398 }
399
400 if( token->IsSameAs( wxT( "#" ) ) )
401 {
402 *token = wxString::Format( "%s", aPath->GetPageNumber() );
403 return true;
404 }
405 else if( token->IsSameAs( wxT( "##" ) ) )
406 {
407 *token = wxString::Format( wxT( "%d" ), (int) schematic->Hierarchy().size() );
408 return true;
409 }
410 else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
411 {
412 *token = aPath->PathHumanReadable();
413 return true;
414 }
415 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
416 {
417 *token = wxEmptyString;
418
419 if( aPath->GetExcludedFromBOM( variant ) || this->ResolveExcludedFromBOM( aPath, variant ) )
420 *token = _( "Excluded from BOM" );
421
422 return true;
423 }
424 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
425 {
426 *token = wxEmptyString;
427
428 if( aPath->GetExcludedFromBoard( variant ) || this->ResolveExcludedFromBoard( aPath, variant ) )
429 *token = _( "Excluded from board" );
430
431 return true;
432 }
433 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
434 {
435 *token = wxEmptyString;
436
437 if( aPath->GetExcludedFromSim( variant ) || this->ResolveExcludedFromSim( aPath, variant ) )
438 *token = _( "Excluded from simulation" );
439
440 return true;
441 }
442 else if( token->IsSameAs( wxT( "DNP" ) ) )
443 {
444 *token = wxEmptyString;
445
446 if( aPath->GetDNP( variant ) || this->ResolveDNP( aPath, variant ) )
447 *token = _( "DNP" );
448
449 return true;
450 }
451
452 // See if parent can resolve it (these will recurse to ancestors)
453
454 if( aPath->size() >= 2 )
455 {
456 SCH_SHEET_PATH path = *aPath;
457 path.pop_back();
458
459 if( path.Last()->ResolveTextVar( &path, token, aDepth + 1 ) )
460 return true;
461 }
462 else
463 {
464 if( schematic->ResolveTextVar( aPath, token, aDepth + 1 ) )
465 return true;
466 }
467
468 return false;
469}
470
471
473{
474 wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
475 wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
476 aItem->GetClass() ) );
477
478 SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
479
480 std::swap( m_pos, sheet->m_pos );
481 std::swap( m_size, sheet->m_size );
482 m_fields.swap( sheet->m_fields );
483 std::swap( m_fieldsAutoplaced, sheet->m_fieldsAutoplaced );
484 m_pins.swap( sheet->m_pins );
485
486 // Update parent pointers after swapping.
487 for( SCH_SHEET_PIN* sheetPin : m_pins )
488 sheetPin->SetParent( this );
489
490 for( SCH_SHEET_PIN* sheetPin : sheet->m_pins )
491 sheetPin->SetParent( sheet );
492
493 for( SCH_FIELD& field : m_fields )
494 field.SetParent( this );
495
496 for( SCH_FIELD& field : sheet->m_fields )
497 field.SetParent( sheet );
498
499 std::swap( m_excludedFromSim, sheet->m_excludedFromSim );
500 std::swap( m_excludedFromBOM, sheet->m_excludedFromBOM );
501 std::swap( m_excludedFromBoard, sheet->m_excludedFromBoard );
502 std::swap( m_DNP, sheet->m_DNP );
503
504 std::swap( m_borderWidth, sheet->m_borderWidth );
505 std::swap( m_borderColor, sheet->m_borderColor );
506 std::swap( m_backgroundColor, sheet->m_backgroundColor );
507 std::swap( m_instances, sheet->m_instances );
508}
509
510
512{
513 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
514 return field;
515
516 m_fields.emplace_back( this, aFieldType );
517 return &m_fields.back();
518}
519
520
521const SCH_FIELD* SCH_SHEET::GetField( FIELD_T aFieldType ) const
522{
523 return FindField( m_fields, aFieldType );
524}
525
526
527SCH_FIELD* SCH_SHEET::GetField( const wxString& aFieldName )
528{
529 return FindField( m_fields, aFieldName );
530}
531
532
533const SCH_FIELD* SCH_SHEET::GetField( const wxString& aFieldName ) const
534{
535 return FindField( m_fields, aFieldName );
536}
537
538
540{
541 return NextFieldOrdinal( m_fields );
542}
543
544
545void SCH_SHEET::SetFields( const std::vector<SCH_FIELD>& aFields )
546{
547 m_fields = aFields;
548
549 // Make sure that we get the UNIX variant of the file path
551}
552
553
555{
556 m_fields.emplace_back( aField );
557 return &m_fields.back();
558}
559
560
561void SCH_SHEET::SetFieldText( const wxString& aFieldName, const wxString& aFieldText, const SCH_SHEET_PATH* aPath,
562 const wxString& aVariantName )
563{
564 wxCHECK( !aFieldName.IsEmpty(), /* void */ );
565
566 SCH_FIELD* field = GetField( aFieldName );
567
568 wxCHECK( field, /* void */ );
569
570 switch( field->GetId() )
571 {
573 {
574 // File names are stored using unix separators.
575 wxString tmp = aFieldText;
576 tmp.Replace( wxT( "\\" ), wxT( "/" ) );
578 break;
579 }
580
582 field->SetText( aFieldText );
583 break;
584
585 default:
586 {
587 wxString defaultText = field->GetText( aPath );
588
589 if( aVariantName.IsEmpty() )
590 {
591 if( aFieldText != defaultText )
592 field->SetText( aFieldText );
593 }
594 else
595 {
596 SCH_SHEET_INSTANCE* instance = getInstance( *aPath );
597
598 wxCHECK( instance, /* void */ );
599
600 if( instance->m_Variants.contains( aVariantName ) )
601 {
602 if( aFieldText != defaultText )
603 instance->m_Variants[aVariantName].m_Fields[aFieldName] = aFieldText;
604 else
605 instance->m_Variants[aVariantName].m_Fields.erase( aFieldName );
606 }
607 else if( aFieldText != defaultText )
608 {
609 SCH_SHEET_VARIANT newVariant( aVariantName );
610
611 newVariant.InitializeAttributes( *this );
612 newVariant.m_Fields[aFieldName] = aFieldText;
613 instance->m_Variants.insert( std::make_pair( aVariantName, newVariant ) );
614 }
615 }
616
617 break;
618 }
619 }
620}
621
622
623wxString SCH_SHEET::GetFieldText( const wxString& aFieldName, const SCH_SHEET_PATH* aPath,
624 const wxString& aVariantName ) const
625{
626 wxCHECK( !aFieldName.IsEmpty(), wxEmptyString );
627
628 const SCH_FIELD* field = GetField( aFieldName );
629
630 wxCHECK( field, wxEmptyString );
631
632 switch( field->GetId() )
633 {
636 return field->GetText();
637 break;
638
639 default:
640 if( aVariantName.IsEmpty() )
641 {
642 return field->GetText();
643 }
644 else
645 {
646 const SCH_SHEET_INSTANCE* instance = getInstance( *aPath );
647
648 if( instance->m_Variants.contains( aVariantName )
649 && instance->m_Variants.at( aVariantName ).m_Fields.contains( aFieldName ) )
650 return instance->m_Variants.at( aVariantName ).m_Fields.at( aFieldName );
651 }
652
653 break;
654 }
655
656 return field->GetText();
657}
658
659
661{
662 wxASSERT( aSheetPin != nullptr );
663 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
664
665 aSheetPin->SetParent( this );
666 m_pins.push_back( aSheetPin );
667 renumberPins();
668}
669
670
671void SCH_SHEET::RemovePin( const SCH_SHEET_PIN* aSheetPin )
672{
673 wxASSERT( aSheetPin != nullptr );
674 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
675
676 for( auto i = m_pins.begin(); i < m_pins.end(); ++i )
677 {
678 if( *i == aSheetPin )
679 {
680 m_pins.erase( i );
681 renumberPins();
682 return;
683 }
684 }
685}
686
687
688bool SCH_SHEET::HasPin( const wxString& aName ) const
689{
690 for( SCH_SHEET_PIN* pin : m_pins )
691 {
692 if( pin->GetText().Cmp( aName ) == 0 )
693 return true;
694 }
695
696 return false;
697}
698
699
700bool SCH_SHEET::doIsConnected( const VECTOR2I& aPosition ) const
701{
702 for( SCH_SHEET_PIN* sheetPin : m_pins )
703 {
704 if( sheetPin->GetPosition() == aPosition )
705 return true;
706 }
707
708 return false;
709}
710
711
713{
714 int leftRight = 0;
715 int topBottom = 0;
716
717 for( SCH_SHEET_PIN* pin : m_pins )
718 {
719 switch( pin->GetSide() )
720 {
721 case SHEET_SIDE::LEFT: leftRight++; break;
722 case SHEET_SIDE::RIGHT: leftRight++; break;
723 case SHEET_SIDE::TOP: topBottom++; break;
724 case SHEET_SIDE::BOTTOM: topBottom++; break;
725 default: break;
726 }
727 }
728
729 return topBottom > 0 && leftRight == 0;
730}
731
732
734{
735 for( SCH_SHEET_PIN* pin : m_pins )
736 {
737 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
738 const SCH_HIERLABEL* HLabel = nullptr;
739
740 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
741 {
742 if( !pin->GetText().Cmp( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
743 {
744 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
745 break;
746 }
747 }
748
749 if( HLabel == nullptr ) // Corresponding hierarchical label not found.
750 return true;
751 }
752
753 return false;
754}
755
756
757int bumpToNextGrid( const int aVal, const int aDirection )
758{
759 constexpr int gridSize = schIUScale.MilsToIU( 50 );
760
761 int base = aVal / gridSize;
762 int excess = abs( aVal % gridSize );
763
764 if( aDirection > 0 )
765 {
766 return ( base + 1 ) * gridSize;
767 }
768 else if( excess > 0 )
769 {
770 return ( base ) * gridSize;
771 }
772 else
773 {
774 return ( base - 1 ) * gridSize;
775 }
776}
777
778
779int SCH_SHEET::GetMinWidth( bool aFromLeft ) const
780{
781 int pinsLeft = m_pos.x + m_size.x;
782 int pinsRight = m_pos.x;
783
784 for( size_t i = 0; i < m_pins.size(); i++ )
785 {
786 SHEET_SIDE edge = m_pins[i]->GetSide();
787
788 if( edge == SHEET_SIDE::TOP || edge == SHEET_SIDE::BOTTOM )
789 {
790 BOX2I pinRect = m_pins[i]->GetBoundingBox();
791
792 pinsLeft = std::min( pinsLeft, pinRect.GetLeft() );
793 pinsRight = std::max( pinsRight, pinRect.GetRight() );
794 }
795 }
796
797 pinsLeft = bumpToNextGrid( pinsLeft, -1 );
798 pinsRight = bumpToNextGrid( pinsRight, 1 );
799
800 int pinMinWidth;
801
802 if( pinsLeft >= pinsRight )
803 pinMinWidth = 0;
804 else if( aFromLeft )
805 pinMinWidth = pinsRight - m_pos.x;
806 else
807 pinMinWidth = m_pos.x + m_size.x - pinsLeft;
808
809 return std::max( pinMinWidth, schIUScale.MilsToIU( MIN_SHEET_WIDTH ) );
810}
811
812
813int SCH_SHEET::GetMinHeight( bool aFromTop ) const
814{
815 int pinsTop = m_pos.y + m_size.y;
816 int pinsBottom = m_pos.y;
817
818 for( size_t i = 0; i < m_pins.size(); i++ )
819 {
820 SHEET_SIDE edge = m_pins[i]->GetSide();
821
822 if( edge == SHEET_SIDE::RIGHT || edge == SHEET_SIDE::LEFT )
823 {
824 BOX2I pinRect = m_pins[i]->GetBoundingBox();
825
826 pinsTop = std::min( pinsTop, pinRect.GetTop() );
827 pinsBottom = std::max( pinsBottom, pinRect.GetBottom() );
828 }
829 }
830
831 pinsTop = bumpToNextGrid( pinsTop, -1 );
832 pinsBottom = bumpToNextGrid( pinsBottom, 1 );
833
834 int pinMinHeight;
835
836 if( pinsTop >= pinsBottom )
837 pinMinHeight = 0;
838 else if( aFromTop )
839 pinMinHeight = pinsBottom - m_pos.y;
840 else
841 pinMinHeight = m_pos.y + m_size.y - pinsTop;
842
843 return std::max( pinMinHeight, schIUScale.MilsToIU( MIN_SHEET_HEIGHT ) );
844}
845
846
848{
849 std::vector<SCH_SHEET_PIN*> pins = m_pins;
850
851 m_pins.clear();
852
853 for( SCH_SHEET_PIN* pin : pins )
854 {
855 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
856 const SCH_HIERLABEL* HLabel = nullptr;
857
858 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
859 {
860 if( pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) == 0 )
861 {
862 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
863 break;
864 }
865 }
866
867 if( HLabel )
868 m_pins.push_back( pin );
869 }
870}
871
872
874{
875 for( SCH_SHEET_PIN* pin : m_pins )
876 {
877 if( pin->HitTest( aPosition ) )
878 return pin;
879 }
880
881 return nullptr;
882}
883
884
886{
887 if( GetBorderWidth() > 0 )
888 return GetBorderWidth();
889
890 if( Schematic() )
892
893 return schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
894}
895
896
898{
899 SCH_FIELD* sheetNameField = GetField( FIELD_T::SHEET_NAME );
900 VECTOR2I textSize = sheetNameField->GetTextSize();
901 int borderMargin = KiROUND( GetPenWidth() / 2.0 ) + 4;
902 int margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.5 );
903
905 {
906 sheetNameField->SetTextPos( m_pos + VECTOR2I( -margin, m_size.y ) );
907 sheetNameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
908 sheetNameField->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
909 sheetNameField->SetTextAngle( ANGLE_VERTICAL );
910 }
911 else
912 {
913 sheetNameField->SetTextPos( m_pos + VECTOR2I( 0, -margin ) );
914 sheetNameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
915 sheetNameField->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
916 sheetNameField->SetTextAngle( ANGLE_HORIZONTAL );
917 }
918
919 SCH_FIELD* sheetFilenameField = GetField( FIELD_T::SHEET_FILENAME );
920
921 textSize = sheetFilenameField->GetTextSize();
922 margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.4 );
923
925 {
926 sheetFilenameField->SetTextPos( m_pos + VECTOR2I( m_size.x + margin, m_size.y ) );
927 sheetFilenameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
928 sheetFilenameField->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
929 sheetFilenameField->SetTextAngle( ANGLE_VERTICAL );
930 }
931 else
932 {
933 sheetFilenameField->SetTextPos( m_pos + VECTOR2I( 0, m_size.y + margin ) );
934 sheetFilenameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
935 sheetFilenameField->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
936 sheetFilenameField->SetTextAngle( ANGLE_HORIZONTAL );
937 }
938
939 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
940 m_fieldsAutoplaced = aAlgo;
941}
942
943
944std::vector<int> SCH_SHEET::ViewGetLayers() const
945{
946 // Sheet pins are drawn by their parent sheet, so the parent needs to draw to LAYER_DANGLING
949}
950
951
953{
955 BOX2I box( m_pos, m_size );
956 int lineWidth = GetPenWidth();
957 int textLength = 0;
958
959 // Calculate bounding box X size:
960 end.x = std::max( m_size.x, textLength );
961
962 // Calculate bounding box pos:
963 end.y = m_size.y;
964 end += m_pos;
965
966 box.SetEnd( end );
967 box.Inflate( lineWidth / 2 );
968
969 return box;
970}
971
972
974{
975 BOX2I bbox = GetBodyBoundingBox();
976
977 for( const SCH_FIELD& field : m_fields )
978 bbox.Merge( field.GetBoundingBox() );
979
980 return bbox;
981}
982
983
985{
986 BOX2I box( m_pos, m_size );
987 return box.GetCenter();
988}
989
990
992{
993 int n = 0;
994
995 if( m_screen )
996 {
997 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SYMBOL_T ) )
998 {
999 SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
1000
1001 if( !symbol->IsPower() )
1002 n++;
1003 }
1004
1005 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
1006 n += static_cast<const SCH_SHEET*>( aItem )->SymbolCount();
1007 }
1008
1009 return n;
1010}
1011
1012
1013bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
1014{
1015 if( m_screen )
1016 {
1017 // Only check the root sheet once and don't recurse.
1018 if( !GetParent() )
1019 {
1020 if( m_screen && m_screen->GetFileName().Cmp( aFilename ) == 0 )
1021 {
1022 *aScreen = m_screen;
1023 return true;
1024 }
1025 }
1026
1027 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
1028 {
1029 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
1030 SCH_SCREEN* screen = sheet->m_screen;
1031
1032 // Must use the screen's path (which is always absolute) rather than the
1033 // sheet's (which could be relative).
1034 if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
1035 {
1036 *aScreen = screen;
1037 return true;
1038 }
1039
1040 if( sheet->SearchHierarchy( aFilename, aScreen ) )
1041 return true;
1042 }
1043 }
1044
1045 return false;
1046}
1047
1048
1050{
1051 if( m_screen )
1052 {
1053 aList->push_back( this );
1054
1055 if( m_screen == aScreen )
1056 return true;
1057
1058 for( EDA_ITEM* item : m_screen->Items().OfType( SCH_SHEET_T ) )
1059 {
1060 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1061
1062 if( sheet->LocatePathOfScreen( aScreen, aList ) )
1063 return true;
1064 }
1065
1066 aList->pop_back();
1067 }
1068
1069 return false;
1070}
1071
1072
1073int SCH_SHEET::CountSheets( const wxString& aFilename ) const
1074{
1075 int count = 0;
1076
1077 if( m_screen )
1078 {
1079 if( m_screen->GetFileName().Cmp( aFilename ) == 0 )
1080 count++;
1081
1082 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
1083 count += static_cast<SCH_SHEET*>( aItem )->CountSheets( aFilename );
1084 }
1085
1086 return count;
1087}
1088
1089
1091{
1092 int count = 1; //1 = this!!
1093
1094 if( m_screen )
1095 {
1096 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
1097 count += static_cast<SCH_SHEET*>( aItem )->CountSheets();
1098 }
1099
1100 return count;
1101}
1102
1103
1105{
1106 int count = CountSheets();
1107
1108 if( IsVirtualRootSheet() )
1109 count--;
1110
1111 return count;
1112}
1113
1114
1115void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1116{
1117 // Don't use GetShownText(); we want to see the variable references here
1118 aList.emplace_back( _( "Sheet Name" ), KIUI::EllipsizeStatusText( aFrame, GetName() ) );
1119
1120 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1121 SCH_SHEET_PATH* currentSheet = nullptr;
1122 wxString currentVariant;
1123
1124 if( schframe )
1125 {
1126 SCH_SHEET_PATH path = schframe->GetCurrentSheet();
1127 path.push_back( this );
1128 currentSheet = &schframe->GetCurrentSheet();
1129 currentVariant = Schematic() ? Schematic()->GetCurrentVariant() : wxString();
1130
1131 aList.emplace_back( _( "Hierarchical Path" ), path.PathHumanReadable( false, true ) );
1132 }
1133
1134 // Don't use GetShownText(); we want to see the variable references here
1135 aList.emplace_back( _( "File Name" ), KIUI::EllipsizeStatusText( aFrame, GetFileName() ) );
1136
1137 wxArrayString msgs;
1138 wxString msg;
1139
1140 if( GetExcludedFromSim() )
1141 msgs.Add( _( "Simulation" ) );
1142
1143 if( GetExcludedFromBOM() )
1144 msgs.Add( _( "BOM" ) );
1145
1146 if( GetExcludedFromBoard() )
1147 msgs.Add( _( "Board" ) );
1148
1149 if( GetDNP( currentSheet, currentVariant ) )
1150 msgs.Add( _( "DNP" ) );
1151
1152 msg = wxJoin( msgs, '|' );
1153 msg.Replace( '|', wxS( ", " ) );
1154
1155 if( !msg.empty() )
1156 aList.emplace_back( _( "Exclude from" ), msg );
1157}
1158
1159
1160std::map<SCH_SHEET_PIN*, SCH_NO_CONNECT*> SCH_SHEET::GetNoConnects() const
1161{
1162 std::map<SCH_SHEET_PIN*, SCH_NO_CONNECT*> noConnects;
1163
1164 if( SCH_SCREEN* screen = dynamic_cast<SCH_SCREEN*>( GetParent() ) )
1165 {
1166 for( SCH_SHEET_PIN* sheetPin : m_pins )
1167 {
1168 for( SCH_ITEM* noConnect : screen->Items().Overlapping( SCH_NO_CONNECT_T, sheetPin->GetTextPos() ) )
1169 noConnects[sheetPin] = static_cast<SCH_NO_CONNECT*>( noConnect );
1170 }
1171 }
1172
1173 return noConnects;
1174}
1175
1176
1178{
1179 VECTOR2I delta = aPosition - m_pos;
1180
1181 m_pos = aPosition;
1182
1183 for( SCH_FIELD& field : m_fields )
1184 field.Move( delta );
1185}
1186
1187
1188void SCH_SHEET::Move( const VECTOR2I& aMoveVector )
1189{
1190 m_pos += aMoveVector;
1191
1192 for( SCH_SHEET_PIN* pin : m_pins )
1193 pin->Move( aMoveVector );
1194
1195 for( SCH_FIELD& field : m_fields )
1196 field.Move( aMoveVector );
1197}
1198
1199
1200void SCH_SHEET::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
1201{
1202 VECTOR2I prev = m_pos;
1203
1204 RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
1205 RotatePoint( &m_size.x, &m_size.y, aRotateCCW ? ANGLE_90 : ANGLE_270 );
1206
1207 if( m_size.x < 0 )
1208 {
1209 m_pos.x += m_size.x;
1210 m_size.x = -m_size.x;
1211 }
1212
1213 if( m_size.y < 0 )
1214 {
1215 m_pos.y += m_size.y;
1216 m_size.y = -m_size.y;
1217 }
1218
1219 // Pins must be rotated first as that's how we determine vertical vs horizontal
1220 // orientation for auto-placement
1221 for( SCH_SHEET_PIN* sheetPin : m_pins )
1222 sheetPin->Rotate( aCenter, aRotateCCW );
1223
1225 {
1227 }
1228 else
1229 {
1230 // Move the fields to the new position because the parent itself has moved.
1231 for( SCH_FIELD& field : m_fields )
1232 {
1233 VECTOR2I pos = field.GetTextPos();
1234 pos.x -= prev.x - m_pos.x;
1235 pos.y -= prev.y - m_pos.y;
1236 field.SetTextPos( pos );
1237 }
1238 }
1239}
1240
1241
1243{
1244 int dy = m_pos.y;
1245
1246 MIRROR( m_pos.y, aCenter );
1247 m_pos.y -= m_size.y;
1248 dy -= m_pos.y; // 0,dy is the move vector for this transform
1249
1250 for( SCH_SHEET_PIN* sheetPin : m_pins )
1251 sheetPin->MirrorVertically( aCenter );
1252
1253 for( SCH_FIELD& field : m_fields )
1254 {
1255 VECTOR2I pos = field.GetTextPos();
1256 pos.y -= dy;
1257 field.SetTextPos( pos );
1258 }
1259}
1260
1261
1263{
1264 int dx = m_pos.x;
1265
1266 MIRROR( m_pos.x, aCenter );
1267 m_pos.x -= m_size.x;
1268 dx -= m_pos.x; // dx,0 is the move vector for this transform
1269
1270 for( SCH_SHEET_PIN* sheetPin : m_pins )
1271 sheetPin->MirrorHorizontally( aCenter );
1272
1273 for( SCH_FIELD& field : m_fields )
1274 {
1275 VECTOR2I pos = field.GetTextPos();
1276 pos.x -= dx;
1277 field.SetTextPos( pos );
1278 }
1279}
1280
1281
1282void SCH_SHEET::SetPosition( const VECTOR2I& aPosition )
1283{
1284 // Remember the sheet and all pin sheet positions must be
1285 // modified. So use Move function to do that.
1286 Move( aPosition - m_pos );
1287}
1288
1289
1290void SCH_SHEET::Resize( const VECTOR2I& aSize )
1291{
1292 if( aSize == m_size )
1293 return;
1294
1295 m_size = aSize;
1296
1297 // Move the fields if we're in autoplace mode
1300
1301 // Move the sheet labels according to the new sheet size.
1302 for( SCH_SHEET_PIN* sheetPin : m_pins )
1303 sheetPin->ConstrainOnEdge( sheetPin->GetPosition(), false );
1304}
1305
1306
1307bool SCH_SHEET::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
1308{
1309 // Sheets are searchable via the child field and pin item text.
1310 return false;
1311}
1312
1313
1315{
1316 int id = 2;
1317
1318 for( SCH_SHEET_PIN* pin : m_pins )
1319 {
1320 pin->SetNumber( id );
1321 id++;
1322 }
1323}
1324
1325
1327{
1328 wxCHECK_MSG( Schematic(), SCH_SHEET_PATH(), "Can't call findSelf without a schematic" );
1329
1330 SCH_SHEET_PATH sheetPath = Schematic()->CurrentSheet();
1331
1332 while( !sheetPath.empty() && sheetPath.Last() != this )
1333 sheetPath.pop_back();
1334
1335 if( sheetPath.empty() )
1336 {
1337 // If we weren't in the hierarchy, then we must be a child of the current sheet.
1338 sheetPath = Schematic()->CurrentSheet();
1339 sheetPath.push_back( const_cast<SCH_SHEET*>( this ) );
1340 }
1341
1342 return sheetPath;
1343}
1344
1345
1346void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1347{
1348 for( SCH_SHEET_PIN* sheetPin : m_pins )
1349 {
1350 wxCHECK2_MSG( sheetPin->Type() == SCH_SHEET_PIN_T, continue,
1351 wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
1352
1353 sheetPin->GetEndPoints( aItemList );
1354 }
1355}
1356
1357
1358bool SCH_SHEET::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1359 std::vector<DANGLING_END_ITEM>& aItemListByPos,
1360 const SCH_SHEET_PATH* aPath )
1361{
1362 bool changed = false;
1363
1364 for( SCH_SHEET_PIN* sheetPin : m_pins )
1365 changed |= sheetPin->UpdateDanglingState( aItemListByType, aItemListByPos );
1366
1367 return changed;
1368}
1369
1370
1372 const SCH_SHEET_PATH* aInstance ) const
1373{
1374 // Do not compare to ourself.
1375 if( aItem == this )
1376 return false;
1377
1378 const SCH_SHEET* sheet = dynamic_cast<const SCH_SHEET*>( aItem );
1379
1380 // Don't compare against a different SCH_ITEM.
1381 wxCHECK( sheet, false );
1382
1383 if( GetPosition() != sheet->GetPosition() )
1384 return true;
1385
1386 // Technically this cannot happen because undo/redo does not support reloading sheet
1387 // file association changes. This was just added so that it doesn't get missed should
1388 // we ever fix the undo/redo issue.
1389 if( ( GetFileName() != sheet->GetFileName() ) || ( GetName() != sheet->GetName() ) )
1390 return true;
1391
1392 if( m_pins.size() != sheet->m_pins.size() )
1393 return true;
1394
1395 for( size_t i = 0; i < m_pins.size(); i++ )
1396 {
1397 if( m_pins[i]->HasConnectivityChanges( sheet->m_pins[i] ) )
1398 return true;
1399 }
1400
1401 return false;
1402}
1403
1404
1405std::vector<VECTOR2I> SCH_SHEET::GetConnectionPoints() const
1406{
1407 std::vector<VECTOR2I> retval;
1408
1409 for( SCH_SHEET_PIN* sheetPin : m_pins )
1410 retval.push_back( sheetPin->GetPosition() );
1411
1412 return retval;
1413}
1414
1415
1416INSPECT_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData,
1417 const std::vector<KICAD_T>& aScanTypes )
1418{
1419 for( KICAD_T scanType : aScanTypes )
1420 {
1421 // If caller wants to inspect my type
1422 if( scanType == SCH_LOCATE_ANY_T || scanType == Type() )
1423 {
1424 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1425 return INSPECT_RESULT::QUIT;
1426 }
1427
1428 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1429 {
1430 // Test the sheet fields.
1431 for( SCH_FIELD& field : m_fields )
1432 {
1433 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1434 return INSPECT_RESULT::QUIT;
1435 }
1436 }
1437
1438 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_SHEET_PIN_T )
1439 {
1440 // Test the sheet labels.
1441 for( SCH_SHEET_PIN* sheetPin : m_pins )
1442 {
1443 if( INSPECT_RESULT::QUIT == aInspector( sheetPin, this ) )
1444 return INSPECT_RESULT::QUIT;
1445 }
1446 }
1447 }
1448
1450}
1451
1452
1453void SCH_SHEET::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
1454{
1455 for( SCH_FIELD& field : m_fields )
1456 aFunction( &field );
1457
1458 for( SCH_SHEET_PIN* pin : m_pins )
1459 aFunction( pin );
1460}
1461
1462
1463wxString SCH_SHEET::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1464{
1465 const SCH_FIELD* sheetnameField = GetField( FIELD_T::SHEET_NAME );
1466
1467 return wxString::Format( _( "Hierarchical Sheet '%s'" ),
1468 aFull ? sheetnameField->GetShownText( false )
1469 : KIUI::EllipsizeMenuText( sheetnameField->GetText() ) );
1470}
1471
1472
1477
1478
1479bool SCH_SHEET::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1480{
1481 BOX2I rect = GetBodyBoundingBox();
1482
1483 rect.Inflate( aAccuracy );
1484
1485 return rect.Contains( aPosition );
1486}
1487
1488
1489bool SCH_SHEET::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1490{
1491 BOX2I rect = aRect;
1492
1493 rect.Inflate( aAccuracy );
1494
1495 if( aContained )
1496 return rect.Contains( GetBodyBoundingBox() );
1497
1498 return rect.Intersects( GetBodyBoundingBox() );
1499}
1500
1501
1502bool SCH_SHEET::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1503{
1504 return KIGEOM::BoxHitTest( aPoly, GetBodyBoundingBox(), aContained );
1505}
1506
1507
1508void SCH_SHEET::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1509 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1510{
1511 if( aBackground && !aPlotter->GetColorMode() )
1512 return;
1513
1514 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1515 COLOR4D borderColor = GetBorderColor();
1516 COLOR4D backgroundColor = GetBackgroundColor();
1517 SCH_SHEET_PATH instance;
1518 wxString variantName;
1519
1520 if( Schematic() )
1521 {
1522 instance = Schematic()->CurrentSheet();
1523 variantName = Schematic()->GetCurrentVariant();
1524 }
1525
1526 bool dnp = GetDNP( &instance, variantName );
1527
1528 if( renderSettings->m_OverrideItemColors || borderColor == COLOR4D::UNSPECIFIED )
1529 borderColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET );
1530
1531 if( renderSettings->m_OverrideItemColors || backgroundColor == COLOR4D::UNSPECIFIED )
1532 backgroundColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET_BACKGROUND );
1533
1534 if( borderColor.m_text && Schematic() )
1535 borderColor = COLOR4D( ResolveText( *borderColor.m_text, &Schematic()->CurrentSheet() ) );
1536
1537 if( backgroundColor.m_text && Schematic() )
1538 backgroundColor = COLOR4D( ResolveText( *backgroundColor.m_text, &Schematic()->CurrentSheet() ) );
1539
1540 if( aDimmed || dnp )
1541 {
1542 borderColor.Desaturate();
1543 borderColor = borderColor.Mix( backgroundColor, 0.5f );
1544 }
1545
1546 if( aBackground && backgroundColor.a > 0.0 )
1547 {
1548 aPlotter->SetColor( backgroundColor );
1549 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::FILLED_SHAPE, 1, 0 );
1550 }
1551 else
1552 {
1553 aPlotter->SetColor( borderColor );
1554
1555 int penWidth = GetEffectivePenWidth( getRenderSettings( aPlotter ) );
1556 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::NO_FILL, penWidth, 0 );
1557 }
1558
1559 // Make the sheet object a clickable hyperlink (e.g. for PDF plotter)
1560 if( aPlotOpts.m_PDFHierarchicalLinks )
1561 {
1562 aPlotter->HyperlinkBox( GetBoundingBox(),
1563 EDA_TEXT::GotoPageHref( findSelf().GetPageNumber() ) );
1564 }
1565 else if( aPlotOpts.m_PDFPropertyPopups )
1566 {
1567 std::vector<wxString> properties;
1568
1569 properties.emplace_back( EDA_TEXT::GotoPageHref( findSelf().GetPageNumber() ) );
1570
1571 for( const SCH_FIELD& field : GetFields() )
1572 {
1573 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), field.GetName(),
1574 field.GetShownText( false ) ) );
1575 }
1576
1577 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
1578 }
1579
1580 // Plot sheet pins
1581 for( SCH_SHEET_PIN* sheetPin : m_pins )
1582 sheetPin->Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed || dnp );
1583
1584 // Plot the fields
1585 for( SCH_FIELD& field : m_fields )
1586 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed || dnp );
1587
1588 if( dnp )
1589 {
1590 BOX2I bbox = GetBodyBoundingBox();
1591 BOX2I pins = GetBoundingBox();
1592 VECTOR2D margins( std::max( bbox.GetX() - pins.GetX(), pins.GetEnd().x - bbox.GetEnd().x ),
1593 std::max( bbox.GetY() - pins.GetY(), pins.GetEnd().y - bbox.GetEnd().y ) );
1594 int strokeWidth = 3.0 * schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
1595
1596 margins.x = std::max( margins.x * 0.6, margins.y * 0.3 );
1597 margins.y = std::max( margins.y * 0.6, margins.x * 0.3 );
1598 bbox.Inflate( KiROUND( margins.x ), KiROUND( margins.y ) );
1599
1600 aPlotter->SetColor( renderSettings->GetLayerColor( LAYER_DNP_MARKER ) );
1601
1602 aPlotter->ThickSegment( bbox.GetOrigin(), bbox.GetEnd(), strokeWidth, nullptr );
1603
1604 aPlotter->ThickSegment( bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
1605 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
1606 strokeWidth, nullptr );
1607 }
1608}
1609
1610
1612{
1613 wxCHECK_MSG( Type() == aItem.Type(), *this,
1614 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1615 GetClass() );
1616
1617 if( &aItem != this )
1618 {
1619 SCH_ITEM::operator=( aItem );
1620
1621 SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
1622
1623 m_pos = sheet->m_pos;
1624 m_size = sheet->m_size;
1625 m_fields = sheet->m_fields;
1626
1627 for( SCH_SHEET_PIN* pin : sheet->m_pins )
1628 {
1629 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
1630 m_pins.back()->SetParent( this );
1631 }
1632
1633 for( const SCH_SHEET_INSTANCE& instance : sheet->m_instances )
1634 m_instances.emplace_back( instance );
1635 }
1636
1637 return *this;
1638}
1639
1640
1641bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const
1642{
1643 if( Type() != aItem.Type() )
1644 return Type() < aItem.Type();
1645
1646 const SCH_SHEET* otherSheet = static_cast<const SCH_SHEET*>( &aItem );
1647
1648 if( GetName() != otherSheet->GetName() )
1649 return GetName() < otherSheet->GetName();
1650
1651 if( GetFileName() != otherSheet->GetFileName() )
1652 return GetFileName() < otherSheet->GetFileName();
1653
1654 return false;
1655}
1656
1657
1658void SCH_SHEET::RemoveInstance( const KIID_PATH& aInstancePath )
1659{
1660 // Search for an existing path and remove it if found (should not occur)
1661 // (search from back to avoid invalidating iterator on remove)
1662 for( int ii = m_instances.size() - 1; ii >= 0; --ii )
1663 {
1664 if( m_instances[ii].m_Path == aInstancePath )
1665 {
1666 wxLogTrace( traceSchSheetPaths, "Removing sheet instance:\n"
1667 " sheet path %s\n"
1668 " page %s, from project %s.",
1669 aInstancePath.AsString(),
1670 m_instances[ii].m_PageNumber,
1671 m_instances[ii].m_ProjectName );
1672
1673 m_instances.erase( m_instances.begin() + ii );
1674 }
1675 }
1676}
1677
1678
1680{
1681 SCH_SHEET_INSTANCE oldInstance;
1682
1683 if( getInstance( oldInstance, aInstance.m_Path ) )
1684 RemoveInstance( aInstance.m_Path );
1685
1686 m_instances.emplace_back( aInstance );
1687
1688}
1689
1690
1692{
1693 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1694 {
1695 // if aSheetPath is found, nothing to do:
1696 if( instance.m_Path == aPath )
1697 return false;
1698 }
1699
1700 wxLogTrace( traceSchSheetPaths, wxT( "Adding instance `%s` to sheet `%s`." ),
1701 aPath.AsString(),
1702 ( GetName().IsEmpty() ) ? wxString( wxT( "root" ) ) : GetName() );
1703
1704 SCH_SHEET_INSTANCE instance;
1705
1706 instance.m_Path = aPath;
1707
1708 // This entry does not exist: add it with an empty page number.
1709 m_instances.emplace_back( instance );
1710 return true;
1711}
1712
1713
1714bool SCH_SHEET::getInstance( SCH_SHEET_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
1715 bool aTestFromEnd ) const
1716{
1717 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1718 {
1719 if( !aTestFromEnd )
1720 {
1721 if( instance.m_Path == aSheetPath )
1722 {
1723 aInstance = instance;
1724 return true;
1725 }
1726 }
1727 else if( instance.m_Path.EndsWith( aSheetPath ) )
1728 {
1729 aInstance = instance;
1730 return true;
1731 }
1732 }
1733
1734 return false;
1735}
1736
1737
1739{
1740 for( SCH_SHEET_INSTANCE& instance : m_instances )
1741 {
1742 if( instance.m_Path == aSheetPath )
1743 return &instance;
1744 }
1745
1746 return nullptr;
1747}
1748
1749
1750const SCH_SHEET_INSTANCE* SCH_SHEET::getInstance( const KIID_PATH& aSheetPath ) const
1751{
1752 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1753 {
1754 if( instance.m_Path == aSheetPath )
1755 return &instance;
1756 }
1757
1758 return nullptr;
1759}
1760
1761
1763{
1764 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1765 {
1766 if( instance.m_Path.size() == 0 )
1767 return true;
1768 }
1769
1770 return false;
1771}
1772
1773
1775{
1776 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1777 {
1778 if( instance.m_Path.size() == 0 )
1779 return instance;
1780 }
1781
1782 wxFAIL;
1783
1785
1786 return dummy;
1787}
1788
1789
1790wxString SCH_SHEET::getPageNumber( const KIID_PATH& aParentPath ) const
1791{
1792 wxString pageNumber;
1793
1794 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1795 {
1796 if( instance.m_Path == aParentPath )
1797 {
1798 pageNumber = instance.m_PageNumber;
1799 break;
1800 }
1801 }
1802
1803 return pageNumber;
1804}
1805
1806
1807void SCH_SHEET::setPageNumber( const KIID_PATH& aPath, const wxString& aPageNumber )
1808{
1809 for( SCH_SHEET_INSTANCE& instance : m_instances )
1810 {
1811 if( instance.m_Path == aPath )
1812 {
1813 instance.m_PageNumber = aPageNumber;
1814 break;
1815 }
1816 }
1817}
1818
1819
1821{
1822 // Avoid self comparison.
1823 if( &aOther == this )
1824 return false;
1825
1826 // A difference in the instance data count implies a page numbering change.
1827 if( GetInstances().size() != aOther.GetInstances().size() )
1828 return true;
1829
1830 std::vector<SCH_SHEET_INSTANCE> instances = GetInstances();
1831 std::vector<SCH_SHEET_INSTANCE> otherInstances = aOther.GetInstances();
1832
1833 // Sorting may not be necessary but there is no guarantee that sheet
1834 // instance data will be in the correct KIID_PATH order. We should
1835 // probably use a std::map instead of a std::vector to store the sheet
1836 // instance data.
1837 std::sort( instances.begin(), instances.end(),
1838 []( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
1839 {
1840 if( aLhs.m_Path > aRhs.m_Path )
1841 return true;
1842
1843 return false;
1844 } );
1845 std::sort( otherInstances.begin(), otherInstances.end(),
1846 []( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
1847 {
1848 if( aLhs.m_Path > aRhs.m_Path )
1849 return true;
1850
1851 return false;
1852 } );
1853
1854 auto itThis = instances.begin();
1855 auto itOther = otherInstances.begin();
1856
1857 while( itThis != instances.end() )
1858 {
1859 if( ( itThis->m_Path == itOther->m_Path )
1860 && ( itThis->m_PageNumber != itOther->m_PageNumber ) )
1861 {
1862 return true;
1863 }
1864
1865 itThis++;
1866 itOther++;
1867 }
1868
1869 return false;
1870}
1871
1872
1873int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
1874{
1875 if( aPageNumberA == aPageNumberB )
1876 return 0; // A == B
1877
1878 // First sort numerically if the page numbers are integers
1879 long pageA, pageB;
1880 bool isIntegerPageA = aPageNumberA.ToLong( &pageA );
1881 bool isIntegerPageB = aPageNumberB.ToLong( &pageB );
1882
1883 if( isIntegerPageA && isIntegerPageB )
1884 {
1885 if( pageA < pageB )
1886 return -1; //A < B
1887 else
1888 return 1; // A > B
1889 }
1890
1891 // Numerical page numbers always before strings
1892 if( isIntegerPageA )
1893 return -1; //A < B
1894 else if( isIntegerPageB )
1895 return 1; // A > B
1896
1897 // If not numeric, then sort as strings using natural sort
1898 int result = StrNumCmp( aPageNumberA, aPageNumberB );
1899
1900 // Divide by zero bad.
1901 wxCHECK( result != 0, 0 );
1902
1904
1905 return result;
1906}
1907
1908
1909bool SCH_SHEET::operator==( const SCH_ITEM& aOther ) const
1910{
1911 if( Type() != aOther.Type() )
1912 return false;
1913
1914 const SCH_SHEET* other = static_cast<const SCH_SHEET*>( &aOther );
1915
1916 if( m_pos != other->m_pos )
1917 return false;
1918
1919 if( m_size != other->m_size )
1920 return false;
1921
1922 if( GetExcludedFromSim() != other->GetExcludedFromSim() )
1923 return false;
1924
1925 if( GetExcludedFromBOM() != other->GetExcludedFromBOM() )
1926 return false;
1927
1928 if( GetExcludedFromBoard() != other->GetExcludedFromBoard() )
1929 return false;
1930
1931 if( GetDNP() != other->GetDNP() )
1932 return false;
1933
1934 if( GetBorderColor() != other->GetBorderColor() )
1935 return false;
1936
1937 if( GetBackgroundColor() != other->GetBackgroundColor() )
1938 return false;
1939
1940 if( GetBorderWidth() != other->GetBorderWidth() )
1941 return false;
1942
1943 if( GetFields().size() != other->GetFields().size() )
1944 return false;
1945
1946 for( size_t i = 0; i < GetFields().size(); ++i )
1947 {
1948 if( !( GetFields()[i] == other->GetFields()[i] ) )
1949 return false;
1950 }
1951
1952 return true;
1953}
1954
1955
1956double SCH_SHEET::Similarity( const SCH_ITEM& aOther ) const
1957{
1958 if( Type() != aOther.Type() )
1959 return 0.0;
1960
1961 const SCH_SHEET* other = static_cast<const SCH_SHEET*>( &aOther );
1962
1963 if( m_screen->GetFileName() == other->m_screen->GetFileName() )
1964 return 1.0;
1965
1966 return 0.0;
1967}
1968
1969
1970void SCH_SHEET::AddVariant( const SCH_SHEET_PATH& aInstance, const SCH_SHEET_VARIANT& aVariant )
1971{
1972 SCH_SHEET_INSTANCE* instance = getInstance( aInstance );
1973
1974 // The instance path must already exist.
1975 if( !instance )
1976 return;
1977
1978 instance->m_Variants.insert( std::make_pair( aVariant.m_Name, aVariant ) );
1979}
1980
1981
1982void SCH_SHEET::DeleteVariant( const KIID_PATH& aPath, const wxString& aVariantName )
1983{
1984 SCH_SHEET_INSTANCE* instance = getInstance( aPath );
1985
1986 // The instance path must already exist.
1987 if( !instance || !instance->m_Variants.contains( aVariantName ) )
1988 return;
1989
1990 instance->m_Variants.erase( aVariantName );
1991}
1992
1993
1994void SCH_SHEET::RenameVariant( const KIID_PATH& aPath, const wxString& aOldName,
1995 const wxString& aNewName )
1996{
1997 SCH_SHEET_INSTANCE* instance = getInstance( aPath );
1998
1999 // The instance path must already exist and contain the old variant.
2000 if( !instance || !instance->m_Variants.contains( aOldName ) )
2001 return;
2002
2003 // Get the variant data, update the name, and re-insert with new key
2004 SCH_SHEET_VARIANT variant = instance->m_Variants[aOldName];
2005 variant.m_Name = aNewName;
2006 instance->m_Variants.erase( aOldName );
2007 instance->m_Variants.insert( std::make_pair( aNewName, variant ) );
2008}
2009
2010
2011void SCH_SHEET::CopyVariant( const KIID_PATH& aPath, const wxString& aSourceVariant,
2012 const wxString& aNewVariant )
2013{
2014 SCH_SHEET_INSTANCE* instance = getInstance( aPath );
2015
2016 // The instance path must already exist and contain the source variant.
2017 if( !instance || !instance->m_Variants.contains( aSourceVariant ) )
2018 return;
2019
2020 // Copy the variant data with a new name
2021 SCH_SHEET_VARIANT variant = instance->m_Variants[aSourceVariant];
2022 variant.m_Name = aNewVariant;
2023 instance->m_Variants.insert( std::make_pair( aNewVariant, variant ) );
2024}
2025
2026
2027void SCH_SHEET::SetDNP( bool aEnable, const SCH_SHEET_PATH* aInstance, const wxString& aVariantName )
2028{
2029 if( !aInstance || aVariantName.IsEmpty() )
2030 {
2031 m_DNP = aEnable;
2032 return;
2033 }
2034
2035 SCH_SHEET_INSTANCE* instance = getInstance( *aInstance );
2036
2037 wxCHECK_MSG( instance, /* void */,
2038 wxString::Format( wxS( "Cannot get DNP attribute for invalid sheet path '%s'." ),
2039 aInstance->PathHumanReadable() ) );
2040
2041 if( aVariantName.IsEmpty() )
2042 {
2043 m_DNP = aEnable;
2044 }
2045 else
2046 {
2047 if( instance->m_Variants.contains( aVariantName ) && ( aEnable != instance->m_Variants[aVariantName].m_DNP ) )
2048 {
2049 instance->m_Variants[aVariantName].m_DNP = aEnable;
2050 }
2051 else
2052 {
2053 SCH_SHEET_VARIANT variant( aVariantName );
2054
2055 variant.InitializeAttributes( *this );
2056 variant.m_DNP = aEnable;
2057 AddVariant( *aInstance, variant );
2058 }
2059 }
2060}
2061
2062
2063bool SCH_SHEET::GetDNP( const SCH_SHEET_PATH* aInstance, const wxString& aVariantName ) const
2064{
2065 if( !aInstance || aVariantName.IsEmpty() )
2066 return m_DNP;
2067
2068 SCH_SHEET_INSTANCE instance;
2069
2070 if( !getInstance( instance, aInstance->Path() ) )
2071 return m_DNP;
2072
2073 if( instance.m_Variants.contains( aVariantName ) )
2074 return instance.m_Variants[aVariantName].m_DNP;
2075
2076 // If the variant has not been defined, return the default DNP setting.
2077 return m_DNP;
2078}
2079
2080
2082{
2083 return GetDNP( &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2084}
2085
2086
2087void SCH_SHEET::SetDNPProp( bool aEnable )
2088{
2089 SetDNP( aEnable, &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2090}
2091
2092
2093void SCH_SHEET::SetExcludedFromSim( bool aEnable, const SCH_SHEET_PATH* aInstance, const wxString& aVariantName )
2094{
2095 if( !aInstance || aVariantName.IsEmpty() )
2096 {
2097 m_excludedFromSim = aEnable;
2098 return;
2099 }
2100
2101 SCH_SHEET_INSTANCE* instance = getInstance( *aInstance );
2102
2103 wxCHECK_MSG( instance, /* void */,
2104 wxString::Format( wxS( "Cannot get m_excludedFromSim attribute for invalid sheet path '%s'." ),
2105 aInstance->PathHumanReadable() ) );
2106
2107 if( aVariantName.IsEmpty() )
2108 {
2109 m_excludedFromSim = aEnable;
2110 }
2111 else
2112 {
2113 if( instance->m_Variants.contains( aVariantName )
2114 && ( aEnable != instance->m_Variants[aVariantName].m_ExcludedFromSim ) )
2115 {
2116 instance->m_Variants[aVariantName].m_ExcludedFromSim = aEnable;
2117 }
2118 else
2119 {
2120 SCH_SHEET_VARIANT variant( aVariantName );
2121
2122 variant.InitializeAttributes( *this );
2123 variant.m_ExcludedFromSim = aEnable;
2124 AddVariant( *aInstance, variant );
2125 }
2126 }
2127}
2128
2129
2130bool SCH_SHEET::GetExcludedFromSim( const SCH_SHEET_PATH* aInstance, const wxString& aVariantName ) const
2131{
2132 if( !aInstance || aVariantName.IsEmpty() )
2133 return m_excludedFromSim;
2134
2135 SCH_SHEET_INSTANCE instance;
2136
2137 if( !getInstance( instance, aInstance->Path() ) )
2138 return m_excludedFromSim;
2139
2140 if( instance.m_Variants.contains( aVariantName ) )
2141 return instance.m_Variants[aVariantName].m_ExcludedFromSim;
2142
2143 // If the variant has not been defined, return the default DNP setting.
2144 return m_excludedFromSim;
2145}
2146
2147
2149{
2150 return GetExcludedFromSim( &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2151}
2152
2153
2155{
2156 SetExcludedFromSim( aEnable, &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2157}
2158
2159
2160void SCH_SHEET::SetExcludedFromBOM( bool aEnable, const SCH_SHEET_PATH* aInstance, const wxString& aVariantName )
2161{
2162 if( !aInstance || aVariantName.IsEmpty() )
2163 {
2164 m_excludedFromBOM = aEnable;
2165 return;
2166 }
2167
2168 SCH_SHEET_INSTANCE* instance = getInstance( *aInstance );
2169
2170 wxCHECK_MSG( instance, /* void */,
2171 wxString::Format( wxS( "Cannot get m_excludedFromBOM attribute for invalid sheet path '%s'." ),
2172 aInstance->PathHumanReadable() ) );
2173
2174 if( aVariantName.IsEmpty() )
2175 {
2176 m_excludedFromBOM = aEnable;
2177 }
2178 else
2179 {
2180 if( instance->m_Variants.contains( aVariantName )
2181 && ( aEnable != instance->m_Variants[aVariantName].m_ExcludedFromBOM ) )
2182 {
2183 instance->m_Variants[aVariantName].m_ExcludedFromBOM = aEnable;
2184 }
2185 else
2186 {
2187 SCH_SHEET_VARIANT variant( aVariantName );
2188
2189 variant.InitializeAttributes( *this );
2190 variant.m_ExcludedFromBOM = aEnable;
2191 AddVariant( *aInstance, variant );
2192 }
2193 }
2194}
2195
2196
2197bool SCH_SHEET::GetExcludedFromBOM( const SCH_SHEET_PATH* aInstance, const wxString& aVariantName ) const
2198{
2199 if( !aInstance || aVariantName.IsEmpty() )
2200 return m_excludedFromBOM;
2201
2202 SCH_SHEET_INSTANCE instance;
2203
2204 if( !getInstance( instance, aInstance->Path() ) )
2205 return m_excludedFromBOM;
2206
2207 if( instance.m_Variants.contains( aVariantName ) )
2208 return instance.m_Variants[aVariantName].m_ExcludedFromBOM;
2209
2210 // If the variant has not been defined, return the default DNP setting.
2211 return m_excludedFromBOM;
2212}
2213
2214
2216{
2217 return GetExcludedFromBOM( &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2218}
2219
2220
2222{
2223 SetExcludedFromBOM( aEnable, &Schematic()->CurrentSheet(), Schematic()->GetCurrentVariant() );
2224}
2225
2226
2227#if defined(DEBUG)
2228
2229void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
2230{
2231 // XML output:
2232 wxString s = GetClass();
2233
2234 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
2235 << TO_UTF8( GetName() ) << '"' << ">\n";
2236
2237 // show all the pins, and check the linked list integrity
2238 for( SCH_SHEET_PIN* sheetPin : m_pins )
2239 sheetPin->Show( nestLevel + 1, os );
2240
2241 NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
2242}
2243
2244#endif
2245
2246static struct SCH_SHEET_DESC
2247{
2249 {
2253
2254 propMgr.AddProperty( new PROPERTY<SCH_SHEET, wxString>( _HKI( "Sheet Name" ),
2256 .SetValidator( []( const wxAny&& aValue, EDA_ITEM* ) -> VALIDATOR_RESULT
2257 {
2258 wxString value;
2259
2260 if( !aValue.GetAs( &value ) )
2261 return {};
2262
2263 wxString msg = GetFieldValidationErrorMessage( FIELD_T::SHEET_NAME, value );
2264
2265 if( msg.empty() )
2266 return {};
2267
2268 return std::make_unique<VALIDATION_ERROR_MSG>( msg );
2269 } );
2270
2271 propMgr.AddProperty( new PROPERTY<SCH_SHEET, int>( _HKI( "Border Width" ),
2274
2275 propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Border Color" ),
2277
2278 propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Background Color" ),
2280
2281 const wxString groupAttributes = _HKI( "Attributes" );
2282
2283 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Board" ),
2285 groupAttributes );
2286 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Simulation" ),
2288 groupAttributes );
2289 propMgr.AddProperty(
2290 new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Bill of Materials" ),
2293 groupAttributes );
2294 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Do not Populate" ),
2296 groupAttributes );
2297 }
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
BITMAPS
A list of all bitmap identifiers.
@ add_hierarchical_subsheet
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr const Vec GetEnd() const
Definition box2.h:208
constexpr coord_type GetY() const
Definition box2.h:204
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr coord_type GetX() const
Definition box2.h:203
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:654
constexpr const Vec GetCenter() const
Definition box2.h:226
constexpr size_type GetHeight() const
Definition box2.h:211
constexpr coord_type GetLeft() const
Definition box2.h:224
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
constexpr const Vec & GetOrigin() const
Definition box2.h:206
constexpr coord_type GetRight() const
Definition box2.h:213
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:293
constexpr coord_type GetTop() const
Definition box2.h:225
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:307
constexpr coord_type GetBottom() const
Definition box2.h:218
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
EDA_ITEM * GetParent() const
Definition eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
virtual VECTOR2I GetTextSize() const
Definition eda_text.h:282
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:110
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:576
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:412
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:404
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::shared_ptr< wxString > m_text
Definition color4d.h:395
double a
Alpha component.
Definition color4d.h:392
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:528
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:292
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString AsString() const
Definition kiid.cpp:393
Definition kiid.h:44
Base plotter engine class.
Definition plotter.h:133
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:164
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
virtual void HyperlinkBox(const BOX2I &aBox, const wxString &aDestinationURL)
Create a clickable hyperlink with a rectangular click area.
Definition plotter.h:503
bool GetColorMode() const
Definition plotter.h:161
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition plotter.cpp:536
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition plotter.h:514
virtual void SetColor(const COLOR4D &color)=0
Container for project specific data.
Definition project.h:62
PROPERTY_BASE & SetValidator(PROPERTY_VALIDATOR_FN &&aValidator)
Definition property.h:349
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Holds all the data relating to one schematic.
Definition schematic.h:90
bool IsTopLevelSheet(const SCH_SHEET *aSheet) const
Check if a sheet is a top-level sheet (direct child of virtual root).
SCHEMATIC_SETTINGS & Settings() const
wxString GetCurrentVariant() const
Return the current variant being edited.
void GetContextualTextVars(wxArrayString *aVars) const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
Schematic editor (Eeschema) main window.
SCH_SHEET_PATH & GetCurrentSheet() const
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
FIELD_T GetId() const
Definition sch_field.h:132
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
void SetText(const wxString &aText) override
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
void SetLocked(bool aLocked) override
Definition sch_item.h:251
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:78
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:724
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:268
bool IsLocked() const override
Definition sch_item.cpp:148
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition sch_item.h:779
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:52
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:377
wxString GetClass() const override
Return the class name.
Definition sch_item.h:172
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:790
SCH_LAYER_ID m_layer
Definition sch_item.h:775
const wxString & GetFileName() const
Definition sch_screen.h:150
bool GetExcludedFromBOM() const
bool empty() const
Forwarded method from std::vector.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
wxString GetPageNumber() const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false, bool aEscapeSheetNames=false) const
Return the sheet path in a human readable form made from the sheet names.
bool GetExcludedFromSim() const
bool GetExcludedFromBoard() const
bool GetDNP() const
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Variant information for a schematic sheet.
void InitializeAttributes(const SCH_SHEET &aSheet)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
friend SCH_SHEET_PATH
Definition sch_sheet.h:581
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition sch_sheet.h:148
friend class SCH_SHEET_PIN
Definition sch_sheet.h:653
VECTOR2I m_size
Definition sch_sheet.h:670
void SetFileName(const wxString &aFilename)
Definition sch_sheet.h:376
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition sch_sheet.h:370
bool getInstance(SCH_SHEET_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
void SetExcludedFromSim(bool aExcludeFromSim, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from simulation flag.
void CopyVariant(const KIID_PATH &aPath, const wxString &aSourceVariant, const wxString &aNewVariant)
void SetSize(const VECTOR2I &aSize)
Definition sch_sheet.h:142
void RemoveInstance(const KIID_PATH &aInstancePath)
void SetDNP(bool aDNP, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
bool addInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
bool HasRootInstance() const
Check to see if this sheet has a root sheet instance.
wxString GetClass() const override
Return the class name.
Definition sch_sheet.h:68
wxString getPageNumber(const KIID_PATH &aParentPath) const
Return the sheet page number for aParentPath.
void SetExcludedFromBOM(bool aExcludeFromBOM, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
int GetPenWidth() const override
std::map< SCH_SHEET_PIN *, SCH_NO_CONNECT * > GetNoConnects() const
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
bool IsTopLevelSheet() const
Check if this sheet is a top-level sheet.
SCH_SHEET_PATH findSelf() const
Get the sheetpath of this sheet.
bool GetDNPProp() const
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
bool GetExcludedFromBoardProp() const
Definition sch_sheet.h:467
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
bool GetExcludedFromBOMProp() const
VECTOR2I m_pos
Definition sch_sheet.h:669
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
Definition sch_sheet.h:87
KIGFX::COLOR4D m_borderColor
Definition sch_sheet.h:672
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
bool m_excludedFromBOM
Definition sch_sheet.h:665
wxString GetName() const
Definition sch_sheet.h:136
void renumberPins()
Renumber the sheet pins in the sheet.
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
SCH_SHEET_PIN * GetPin(const VECTOR2I &aPosition)
Return the sheet pin item found at aPosition in the sheet.
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool operator<(const SCH_ITEM &aItem) const override
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
void SetPositionIgnoringPins(const VECTOR2I &aPosition)
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
std::vector< SCH_SHEET_INSTANCE > m_instances
Definition sch_sheet.h:675
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
bool m_excludedFromSim
Definition sch_sheet.h:664
void SetPosition(const VECTOR2I &aPosition) override
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition sch_sheet.h:151
int SymbolCount() const
Count our own symbols, without the power symbols.
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
void SetDNPProp(bool aEnable)
void AddInstance(const SCH_SHEET_INSTANCE &aInstance)
int GetMinWidth(bool aFromLeft) const
Return the minimum width of the sheet based on the widths of the sheet pin text.
bool operator==(const SCH_ITEM &aOther) const override
SCH_SCREEN * m_screen
Definition sch_sheet.h:657
std::vector< int > ViewGetLayers() const override
Return the layers the item is drawn on (which may be more than its "home" layer)
std::vector< SCH_FIELD > m_fields
Definition sch_sheet.h:662
void RenameVariant(const KIID_PATH &aPath, const wxString &aOldName, const wxString &aNewName)
VECTOR2I GetSize() const
Definition sch_sheet.h:141
KIGFX::COLOR4D m_backgroundColor
Definition sch_sheet.h:673
void SetExcludedFromBoard(bool aExclude, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear exclude from board netlist flag.
Definition sch_sheet.h:455
void DeleteVariant(const KIID_PATH &aPath, const wxString &aVariantName)
SCH_SHEET(EDA_ITEM *aParent=nullptr, const VECTOR2I &aPos=VECTOR2I(0, 0), VECTOR2I aSize=VECTOR2I(schIUScale.MilsToIU(MIN_SHEET_WIDTH), schIUScale.MilsToIU(MIN_SHEET_HEIGHT)))
Definition sch_sheet.cpp:55
void SetName(const wxString &aName)
Definition sch_sheet.h:137
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this sheet.
void SetExcludedFromSimProp(bool aEnable)
VECTOR2I GetPosition() const override
Definition sch_sheet.h:490
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
bool HasPin(const wxString &aName) const
Check if the sheet already has a sheet pin named aName.
static int ComparePageNum(const wxString &aPageNumberA, const wxString &aPageNumberB)
Compare page numbers of schematic sheets.
void SetFieldText(const wxString &aFieldName, const wxString &aFieldText, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString)
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
int CountActiveSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition sch_sheet.cpp:82
int GetScreenCount() const
Return the number of times the associated screen for the sheet is being used.
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
SCH_SHEET & operator=(const SCH_ITEM &aSheet)
bool HasPageNumberChanges(const SCH_SHEET &aOther) const
Check if the instance data of this sheet has any changes compared to aOther.
const SCH_SHEET_INSTANCE & GetRootInstance() const
Return the root sheet instance data.
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
bool m_excludedFromBoard
Definition sch_sheet.h:666
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
KIGFX::COLOR4D GetBorderColor() const
Definition sch_sheet.h:147
std::vector< SCH_SHEET_PIN * > m_pins
Definition sch_sheet.h:661
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &aScanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
void SetBorderWidth(int aWidth)
Definition sch_sheet.h:145
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a @aField to the list of fields.
void setPageNumber(const KIID_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
bool IsVirtualRootSheet() const
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
int GetMinHeight(bool aFromTop) const
Return the minimum height that the sheet can be resized based on the sheet pin positions.
bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flags.
bool GetExcludedFromSimProp() const
void SetExcludedFromBoardProp(bool aExclude)
Definition sch_sheet.h:468
int m_borderWidth
Definition sch_sheet.h:671
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos, const SCH_SHEET_PATH *aPath=nullptr) override
Test the schematic item to aItemList to check if it's dangling state has changed.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition sch_sheet.h:461
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
int GetBorderWidth() const
Definition sch_sheet.h:144
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
bool m_DNP
Definition sch_sheet.h:667
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:227
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
void SetExcludedFromBOMProp(bool aEnable)
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
void AddVariant(const SCH_SHEET_PATH &aInstance, const SCH_SHEET_VARIANT &aVariant)
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
Definition sch_sheet.h:505
bool IsVerticalOrientation() const
bool HitTest(const VECTOR2I &aPosition, int aAccuracy) const override
Test if aPosition is inside or on the boundary of this item.
KIGFX::COLOR4D GetBackgroundColor() const
Definition sch_sheet.h:150
Schematic symbol object.
Definition sch_symbol.h:69
bool IsPower() const override
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
wxString m_Name
bool m_ExcludedFromBOM
std::map< wxString, wxString > m_Fields
bool m_ExcludedFromSim
A type-safe container of any type.
Definition ki_any.h:92
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:416
RECURSE_MODE
Definition eda_item.h:48
INSPECT_RESULT
Definition eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:89
@ NO_FILL
Definition eda_shape.h:60
@ FILLED_SHAPE
Fill with object color.
Definition eda_shape.h:61
a few functions useful in geometry calculations.
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
KIID niluuid(0)
@ LAYER_DANGLING
Definition layer_ids.h:475
@ LAYER_SHEETNAME
Definition layer_ids.h:470
@ LAYER_SHEET_BACKGROUND
Definition layer_ids.h:483
@ LAYER_HIERLABEL
Definition layer_ids.h:455
@ LAYER_SHEETFIELDS
Definition layer_ids.h:472
@ LAYER_SHEET
Definition layer_ids.h:469
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:493
@ LAYER_SHEETFILENAME
Definition layer_ids.h:471
@ LAYER_DNP_MARKER
Definition layer_ids.h:476
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition mirror.h:41
Message panel definition file.
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
KICOMMON_API wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:96
KICOMMON_API void PackColor(types::Color &aOutput, const KIGFX::COLOR4D &aInput)
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API KIGFX::COLOR4D UnpackColor(const types::Color &aInput)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
#define _HKI(x)
Definition page_info.cpp:40
see class PGM_BASE
#define TYPE_HASH(x)
Definition property.h:74
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
std::optional< std::unique_ptr< VALIDATION_ERROR > > VALIDATOR_RESULT
Null optional means validation succeeded.
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
Definition sch_field.h:383
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition sch_field.h:372
AUTOPLACE_ALGO
Definition sch_item.h:65
@ AUTOPLACE_MANUAL
Definition sch_item.h:68
@ AUTOPLACE_AUTO
Definition sch_item.h:67
int bumpToNextGrid(const int aVal, const int aDirection)
static struct SCH_SHEET_DESC _SCH_SHEET_DESC
#define MIN_SHEET_HEIGHT
Definition sch_sheet.h:37
#define MIN_SHEET_WIDTH
Definition sch_sheet.h:36
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
bool m_PDFPropertyPopups
Definition sch_plotter.h:61
bool m_PDFHierarchicalLinks
Definition sch_plotter.h:62
A simple container for sheet instance information.
std::map< wxString, SCH_SHEET_VARIANT > m_Variants
A list of sheet variants.
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
#define DO_TRANSLATE
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
std::string path
KIBIS_PIN * pin
VECTOR2I end
wxString result
Test unit parsing edge cases and error handling.
int delta
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_TOP
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:71
@ SCH_NO_CONNECT_T
Definition typeinfo.h:157
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_FIELD_T
Definition typeinfo.h:147
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:196
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_HIER_LABEL_T
Definition typeinfo.h:166
@ SCH_SHEET_PIN_T
Definition typeinfo.h:171
wxString GetFieldValidationErrorMessage(FIELD_T aFieldId, const wxString &aValue)
Return the error message if aValue is invalid for aFieldId.
Custom text control validator definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682