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