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 <sch_sheet.h>
41#include <sch_sheet_path.h>
42#include <sch_sheet_pin.h>
43#include <sch_symbol.h>
44#include <sch_painter.h>
45#include <schematic.h>
48#include <trace_helpers.h>
49#include <validators.h>
51#include <pgm_base.h>
52#include <wx/log.h>
53
79
80
82 SCH_ITEM( aSheet )
83{
84 m_pos = aSheet.m_pos;
85 m_size = aSheet.m_size;
86 m_layer = aSheet.m_layer;
87 const_cast<KIID&>( m_Uuid ) = aSheet.m_Uuid;
88 m_fields = aSheet.m_fields;
90 m_screen = aSheet.m_screen;
91
95 m_DNP = aSheet.m_DNP;
96
100 m_instances = aSheet.m_instances;
101
102 for( SCH_SHEET_PIN* pin : aSheet.m_pins )
103 {
104 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
105 m_pins.back()->SetParent( this );
106 }
107
108 for( SCH_FIELD& field : m_fields )
109 field.SetParent( this );
110
111 if( m_screen )
112 m_screen->IncRefCount();
113}
114
115
117{
118 // also, look at the associated sheet & its reference count
119 // perhaps it should be deleted also.
120 if( m_screen )
121 {
122 m_screen->DecRefCount();
123
124 if( m_screen->GetRefCount() == 0 )
125 delete m_screen;
126 }
127
128 // We own our pins; delete them
129 for( SCH_SHEET_PIN* pin : m_pins )
130 delete pin;
131}
132
133
135{
136 return new SCH_SHEET( *this );
137}
138
139
141{
142 if( aScreen == m_screen )
143 return;
144
145 if( m_screen != nullptr )
146 {
147 m_screen->DecRefCount();
148
149 if( m_screen->GetRefCount() == 0 )
150 {
151 delete m_screen;
152 m_screen = nullptr;
153 }
154 }
155
156 m_screen = aScreen;
157
158 if( m_screen )
159 m_screen->IncRefCount();
160}
161
162
164{
165 if( m_screen == nullptr )
166 return 0;
167
168 return m_screen->GetRefCount();
169}
170
171
173{
174 wxCHECK_MSG( Schematic(), false, "Can't call IsVirtualRootSheet without setting a schematic" );
175
176 return m_Uuid == niluuid;
177}
178
179
181{
182 wxCHECK_MSG( Schematic(), false, "Can't call IsTopLevelSheet without setting a schematic" );
183
184 return Schematic()->IsTopLevelSheet( this );
185}
186
187
188void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
189{
190 auto add =
191 [&]( const wxString& aVar )
192 {
193 if( !alg::contains( *aVars, aVar ) )
194 aVars->push_back( aVar );
195 };
196
197 for( const SCH_FIELD& field : m_fields )
198 {
199 if( field.IsMandatory() )
200 add( field.GetCanonicalName().Upper() );
201 else
202 add( field.GetName() );
203 }
204
205 SCH_SHEET_PATH sheetPath = findSelf();
206
207 if( sheetPath.size() >= 2 )
208 {
209 sheetPath.pop_back();
210 sheetPath.Last()->GetContextualTextVars( aVars );
211 }
212 else if( Schematic() )
213 {
215 }
216
217 add( wxT( "#" ) );
218 add( wxT( "##" ) );
219 add( wxT( "SHEETPATH" ) );
220 add( wxT( "EXCLUDE_FROM_BOM" ) );
221 add( wxT( "EXCLUDE_FROM_BOARD" ) );
222 add( wxT( "EXCLUDE_FROM_SIM" ) );
223 add( wxT( "DNP" ) );
224 add( wxT( "ERC_ERROR <message_text>" ) );
225 add( wxT( "ERC_WARNING <message_text>" ) );
226
227 m_screen->GetTitleBlock().GetContextualTextVars( aVars );
228}
229
230
231bool SCH_SHEET::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
232{
233 wxCHECK( aPath, false );
234
235 SCHEMATIC* schematic = Schematic();
236
237 if( !schematic )
238 return false;
239
240 if( token->Contains( ':' ) )
241 {
242 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
243 return true;
244 }
245
246 for( const SCH_FIELD& field : m_fields )
247 {
248 wxString fieldName = field.IsMandatory() ? field.GetCanonicalName().Upper()
249 : field.GetName();
250
251 if( token->IsSameAs( fieldName ) )
252 {
253 *token = field.GetShownText( aPath, false, aDepth + 1 );
254 return true;
255 }
256 }
257
258 PROJECT* project = &schematic->Project();
259
260 // We cannot resolve text variables initially on load as we need to first load the screen and
261 // then parse the hierarchy. So skip the resolution if the screen isn't set yet
262 if( m_screen && m_screen->GetTitleBlock().TextVarResolver( token, project ) )
263 {
264 return true;
265 }
266
267 if( token->IsSameAs( wxT( "#" ) ) )
268 {
269 *token = wxString::Format( "%s", aPath->GetPageNumber() );
270 return true;
271 }
272 else if( token->IsSameAs( wxT( "##" ) ) )
273 {
274 *token = wxString::Format( wxT( "%d" ), (int) schematic->Hierarchy().size() );
275 return true;
276 }
277 else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
278 {
279 *token = aPath->PathHumanReadable();
280 return true;
281 }
282 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
283 {
284 *token = wxEmptyString;
285
286 if( aPath->GetExcludedFromBOM() || this->ResolveExcludedFromBOM() )
287 *token = _( "Excluded from BOM" );
288
289 return true;
290 }
291 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
292 {
293 *token = wxEmptyString;
294
295 if( aPath->GetExcludedFromBoard() || this->ResolveExcludedFromBoard() )
296 *token = _( "Excluded from board" );
297
298 return true;
299 }
300 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
301 {
302 *token = wxEmptyString;
303
304 if( aPath->GetExcludedFromSim() || this->ResolveExcludedFromSim() )
305 *token = _( "Excluded from simulation" );
306
307 return true;
308 }
309 else if( token->IsSameAs( wxT( "DNP" ) ) )
310 {
311 *token = wxEmptyString;
312
313 if( aPath->GetDNP() || this->ResolveDNP() )
314 *token = _( "DNP" );
315
316 return true;
317 }
318
319 // See if parent can resolve it (these will recurse to ancestors)
320
321 if( aPath->size() >= 2 )
322 {
323 SCH_SHEET_PATH path = *aPath;
324 path.pop_back();
325
326 if( path.Last()->ResolveTextVar( &path, token, aDepth + 1 ) )
327 return true;
328 }
329 else
330 {
331 if( schematic->ResolveTextVar( aPath, token, aDepth + 1 ) )
332 return true;
333 }
334
335 return false;
336}
337
338
340{
341 wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
342 wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
343 aItem->GetClass() ) );
344
345 SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
346
347 std::swap( m_pos, sheet->m_pos );
348 std::swap( m_size, sheet->m_size );
349 m_fields.swap( sheet->m_fields );
350 std::swap( m_fieldsAutoplaced, sheet->m_fieldsAutoplaced );
351 m_pins.swap( sheet->m_pins );
352
353 // Update parent pointers after swapping.
354 for( SCH_SHEET_PIN* sheetPin : m_pins )
355 sheetPin->SetParent( this );
356
357 for( SCH_SHEET_PIN* sheetPin : sheet->m_pins )
358 sheetPin->SetParent( sheet );
359
360 for( SCH_FIELD& field : m_fields )
361 field.SetParent( this );
362
363 for( SCH_FIELD& field : sheet->m_fields )
364 field.SetParent( sheet );
365
366 std::swap( m_excludedFromSim, sheet->m_excludedFromSim );
367 std::swap( m_excludedFromBOM, sheet->m_excludedFromBOM );
368 std::swap( m_excludedFromBoard, sheet->m_excludedFromBoard );
369 std::swap( m_DNP, sheet->m_DNP );
370
371 std::swap( m_borderWidth, sheet->m_borderWidth );
372 std::swap( m_borderColor, sheet->m_borderColor );
373 std::swap( m_backgroundColor, sheet->m_backgroundColor );
374 std::swap( m_instances, sheet->m_instances );
375}
376
377
379{
380 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
381 return field;
382
383 m_fields.emplace_back( this, aFieldType );
384 return &m_fields.back();
385}
386
387
388const SCH_FIELD* SCH_SHEET::GetField( FIELD_T aFieldType ) const
389{
390 return FindField( m_fields, aFieldType );
391}
392
393
395{
396 return NextFieldOrdinal( m_fields );
397}
398
399
400void SCH_SHEET::SetFields( const std::vector<SCH_FIELD>& aFields )
401{
402 m_fields = aFields;
403
404 // Make sure that we get the UNIX variant of the file path
406}
407
408
410{
411 wxASSERT( aSheetPin != nullptr );
412 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
413
414 aSheetPin->SetParent( this );
415 m_pins.push_back( aSheetPin );
416 renumberPins();
417}
418
419
420void SCH_SHEET::RemovePin( const SCH_SHEET_PIN* aSheetPin )
421{
422 wxASSERT( aSheetPin != nullptr );
423 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
424
425 for( auto i = m_pins.begin(); i < m_pins.end(); ++i )
426 {
427 if( *i == aSheetPin )
428 {
429 m_pins.erase( i );
430 renumberPins();
431 return;
432 }
433 }
434}
435
436
437bool SCH_SHEET::HasPin( const wxString& aName ) const
438{
439 for( SCH_SHEET_PIN* pin : m_pins )
440 {
441 if( pin->GetText().Cmp( aName ) == 0 )
442 return true;
443 }
444
445 return false;
446}
447
448
449bool SCH_SHEET::doIsConnected( const VECTOR2I& aPosition ) const
450{
451 for( SCH_SHEET_PIN* sheetPin : m_pins )
452 {
453 if( sheetPin->GetPosition() == aPosition )
454 return true;
455 }
456
457 return false;
458}
459
460
462{
463 int leftRight = 0;
464 int topBottom = 0;
465
466 for( SCH_SHEET_PIN* pin : m_pins )
467 {
468 switch( pin->GetSide() )
469 {
470 case SHEET_SIDE::LEFT: leftRight++; break;
471 case SHEET_SIDE::RIGHT: leftRight++; break;
472 case SHEET_SIDE::TOP: topBottom++; break;
473 case SHEET_SIDE::BOTTOM: topBottom++; break;
474 default: break;
475 }
476 }
477
478 return topBottom > 0 && leftRight == 0;
479}
480
481
483{
484 for( SCH_SHEET_PIN* pin : m_pins )
485 {
486 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
487 const SCH_HIERLABEL* HLabel = nullptr;
488
489 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
490 {
491 if( !pin->GetText().Cmp( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
492 {
493 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
494 break;
495 }
496 }
497
498 if( HLabel == nullptr ) // Corresponding hierarchical label not found.
499 return true;
500 }
501
502 return false;
503}
504
505
506int bumpToNextGrid( const int aVal, const int aDirection )
507{
508 constexpr int gridSize = schIUScale.MilsToIU( 50 );
509
510 int base = aVal / gridSize;
511 int excess = abs( aVal % gridSize );
512
513 if( aDirection > 0 )
514 {
515 return ( base + 1 ) * gridSize;
516 }
517 else if( excess > 0 )
518 {
519 return ( base ) * gridSize;
520 }
521 else
522 {
523 return ( base - 1 ) * gridSize;
524 }
525}
526
527
528int SCH_SHEET::GetMinWidth( bool aFromLeft ) const
529{
530 int pinsLeft = m_pos.x + m_size.x;
531 int pinsRight = m_pos.x;
532
533 for( size_t i = 0; i < m_pins.size(); i++ )
534 {
535 SHEET_SIDE edge = m_pins[i]->GetSide();
536
537 if( edge == SHEET_SIDE::TOP || edge == SHEET_SIDE::BOTTOM )
538 {
539 BOX2I pinRect = m_pins[i]->GetBoundingBox();
540
541 pinsLeft = std::min( pinsLeft, pinRect.GetLeft() );
542 pinsRight = std::max( pinsRight, pinRect.GetRight() );
543 }
544 }
545
546 pinsLeft = bumpToNextGrid( pinsLeft, -1 );
547 pinsRight = bumpToNextGrid( pinsRight, 1 );
548
549 int pinMinWidth;
550
551 if( pinsLeft >= pinsRight )
552 pinMinWidth = 0;
553 else if( aFromLeft )
554 pinMinWidth = pinsRight - m_pos.x;
555 else
556 pinMinWidth = m_pos.x + m_size.x - pinsLeft;
557
558 return std::max( pinMinWidth, schIUScale.MilsToIU( MIN_SHEET_WIDTH ) );
559}
560
561
562int SCH_SHEET::GetMinHeight( bool aFromTop ) const
563{
564 int pinsTop = m_pos.y + m_size.y;
565 int pinsBottom = m_pos.y;
566
567 for( size_t i = 0; i < m_pins.size(); i++ )
568 {
569 SHEET_SIDE edge = m_pins[i]->GetSide();
570
571 if( edge == SHEET_SIDE::RIGHT || edge == SHEET_SIDE::LEFT )
572 {
573 BOX2I pinRect = m_pins[i]->GetBoundingBox();
574
575 pinsTop = std::min( pinsTop, pinRect.GetTop() );
576 pinsBottom = std::max( pinsBottom, pinRect.GetBottom() );
577 }
578 }
579
580 pinsTop = bumpToNextGrid( pinsTop, -1 );
581 pinsBottom = bumpToNextGrid( pinsBottom, 1 );
582
583 int pinMinHeight;
584
585 if( pinsTop >= pinsBottom )
586 pinMinHeight = 0;
587 else if( aFromTop )
588 pinMinHeight = pinsBottom - m_pos.y;
589 else
590 pinMinHeight = m_pos.y + m_size.y - pinsTop;
591
592 return std::max( pinMinHeight, schIUScale.MilsToIU( MIN_SHEET_HEIGHT ) );
593}
594
595
597{
598 std::vector<SCH_SHEET_PIN*> pins = m_pins;
599
600 m_pins.clear();
601
602 for( SCH_SHEET_PIN* pin : pins )
603 {
604 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
605 const SCH_HIERLABEL* HLabel = nullptr;
606
607 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
608 {
609 if( pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) == 0 )
610 {
611 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
612 break;
613 }
614 }
615
616 if( HLabel )
617 m_pins.push_back( pin );
618 }
619}
620
621
623{
624 for( SCH_SHEET_PIN* pin : m_pins )
625 {
626 if( pin->HitTest( aPosition ) )
627 return pin;
628 }
629
630 return nullptr;
631}
632
633
635{
636 if( GetBorderWidth() > 0 )
637 return GetBorderWidth();
638
639 if( Schematic() )
641
642 return schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
643}
644
645
647{
648 SCH_FIELD* sheetNameField = GetField( FIELD_T::SHEET_NAME );
649 VECTOR2I textSize = sheetNameField->GetTextSize();
650 int borderMargin = KiROUND( GetPenWidth() / 2.0 ) + 4;
651 int margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.5 );
652
654 {
655 sheetNameField->SetTextPos( m_pos + VECTOR2I( -margin, m_size.y ) );
656 sheetNameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
657 sheetNameField->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
658 sheetNameField->SetTextAngle( ANGLE_VERTICAL );
659 }
660 else
661 {
662 sheetNameField->SetTextPos( m_pos + VECTOR2I( 0, -margin ) );
663 sheetNameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
664 sheetNameField->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
665 sheetNameField->SetTextAngle( ANGLE_HORIZONTAL );
666 }
667
668 SCH_FIELD* sheetFilenameField = GetField( FIELD_T::SHEET_FILENAME );
669
670 textSize = sheetFilenameField->GetTextSize();
671 margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.4 );
672
674 {
675 sheetFilenameField->SetTextPos( m_pos + VECTOR2I( m_size.x + margin, m_size.y ) );
676 sheetFilenameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
677 sheetFilenameField->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
678 sheetFilenameField->SetTextAngle( ANGLE_VERTICAL );
679 }
680 else
681 {
682 sheetFilenameField->SetTextPos( m_pos + VECTOR2I( 0, m_size.y + margin ) );
683 sheetFilenameField->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
684 sheetFilenameField->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
685 sheetFilenameField->SetTextAngle( ANGLE_HORIZONTAL );
686 }
687
688 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
689 m_fieldsAutoplaced = aAlgo;
690}
691
692
693std::vector<int> SCH_SHEET::ViewGetLayers() const
694{
695 // Sheet pins are drawn by their parent sheet, so the parent needs to draw to LAYER_DANGLING
698}
699
700
702{
704 BOX2I box( m_pos, m_size );
705 int lineWidth = GetPenWidth();
706 int textLength = 0;
707
708 // Calculate bounding box X size:
709 end.x = std::max( m_size.x, textLength );
710
711 // Calculate bounding box pos:
712 end.y = m_size.y;
713 end += m_pos;
714
715 box.SetEnd( end );
716 box.Inflate( lineWidth / 2 );
717
718 return box;
719}
720
721
723{
724 BOX2I bbox = GetBodyBoundingBox();
725
726 for( const SCH_FIELD& field : m_fields )
727 bbox.Merge( field.GetBoundingBox() );
728
729 return bbox;
730}
731
732
734{
735 BOX2I box( m_pos, m_size );
736 return box.GetCenter();
737}
738
739
741{
742 int n = 0;
743
744 if( m_screen )
745 {
746 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SYMBOL_T ) )
747 {
748 SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
749
750 if( !symbol->IsPower() )
751 n++;
752 }
753
754 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
755 n += static_cast<const SCH_SHEET*>( aItem )->SymbolCount();
756 }
757
758 return n;
759}
760
761
762bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
763{
764 if( m_screen )
765 {
766 // Only check the root sheet once and don't recurse.
767 if( !GetParent() )
768 {
769 if( m_screen && m_screen->GetFileName().Cmp( aFilename ) == 0 )
770 {
771 *aScreen = m_screen;
772 return true;
773 }
774 }
775
776 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
777 {
778 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
779 SCH_SCREEN* screen = sheet->m_screen;
780
781 // Must use the screen's path (which is always absolute) rather than the
782 // sheet's (which could be relative).
783 if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
784 {
785 *aScreen = screen;
786 return true;
787 }
788
789 if( sheet->SearchHierarchy( aFilename, aScreen ) )
790 return true;
791 }
792 }
793
794 return false;
795}
796
797
799{
800 if( m_screen )
801 {
802 aList->push_back( this );
803
804 if( m_screen == aScreen )
805 return true;
806
807 for( EDA_ITEM* item : m_screen->Items().OfType( SCH_SHEET_T ) )
808 {
809 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
810
811 if( sheet->LocatePathOfScreen( aScreen, aList ) )
812 return true;
813 }
814
815 aList->pop_back();
816 }
817
818 return false;
819}
820
821
822int SCH_SHEET::CountSheets( const wxString& aFilename ) const
823{
824 int count = 0;
825
826 if( m_screen )
827 {
828 if( m_screen->GetFileName().Cmp( aFilename ) == 0 )
829 count++;
830
831 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
832 count += static_cast<SCH_SHEET*>( aItem )->CountSheets( aFilename );
833 }
834
835 return count;
836}
837
838
840{
841 int count = 1; //1 = this!!
842
843 if( m_screen )
844 {
845 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
846 count += static_cast<SCH_SHEET*>( aItem )->CountSheets();
847 }
848
849 return count;
850}
851
852
854{
855 int count = CountSheets();
856
857 if( IsVirtualRootSheet() )
858 count--;
859
860 return count;
861}
862
863
864void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
865{
866 // Don't use GetShownText(); we want to see the variable references here
867 aList.emplace_back( _( "Sheet Name" ), KIUI::EllipsizeStatusText( aFrame, GetName() ) );
868
869 if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
870 {
871 SCH_SHEET_PATH path = schframe->GetCurrentSheet();
872 path.push_back( this );
873
874 aList.emplace_back( _( "Hierarchical Path" ), path.PathHumanReadable( false, true ) );
875 }
876
877 // Don't use GetShownText(); we want to see the variable references here
878 aList.emplace_back( _( "File Name" ), KIUI::EllipsizeStatusText( aFrame, GetFileName() ) );
879
880 wxArrayString msgs;
881 wxString msg;
882
883 if( GetExcludedFromSim() )
884 msgs.Add( _( "Simulation" ) );
885
886 if( GetExcludedFromBOM() )
887 msgs.Add( _( "BOM" ) );
888
890 msgs.Add( _( "Board" ) );
891
892 if( GetDNP() )
893 msgs.Add( _( "DNP" ) );
894
895 msg = wxJoin( msgs, '|' );
896 msg.Replace( '|', wxS( ", " ) );
897
898 if( !msg.empty() )
899 aList.emplace_back( _( "Exclude from" ), msg );
900}
901
902
904{
905 VECTOR2I delta = aPosition - m_pos;
906
907 m_pos = aPosition;
908
909 for( SCH_FIELD& field : m_fields )
910 field.Move( delta );
911}
912
913
914void SCH_SHEET::Move( const VECTOR2I& aMoveVector )
915{
916 m_pos += aMoveVector;
917
918 for( SCH_SHEET_PIN* pin : m_pins )
919 pin->Move( aMoveVector );
920
921 for( SCH_FIELD& field : m_fields )
922 field.Move( aMoveVector );
923}
924
925
926void SCH_SHEET::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
927{
928 VECTOR2I prev = m_pos;
929
930 RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
931 RotatePoint( &m_size.x, &m_size.y, aRotateCCW ? ANGLE_90 : ANGLE_270 );
932
933 if( m_size.x < 0 )
934 {
935 m_pos.x += m_size.x;
936 m_size.x = -m_size.x;
937 }
938
939 if( m_size.y < 0 )
940 {
941 m_pos.y += m_size.y;
942 m_size.y = -m_size.y;
943 }
944
945 // Pins must be rotated first as that's how we determine vertical vs horizontal
946 // orientation for auto-placement
947 for( SCH_SHEET_PIN* sheetPin : m_pins )
948 sheetPin->Rotate( aCenter, aRotateCCW );
949
951 {
953 }
954 else
955 {
956 // Move the fields to the new position because the parent itself has moved.
957 for( SCH_FIELD& field : m_fields )
958 {
959 VECTOR2I pos = field.GetTextPos();
960 pos.x -= prev.x - m_pos.x;
961 pos.y -= prev.y - m_pos.y;
962 field.SetTextPos( pos );
963 }
964 }
965}
966
967
969{
970 int dy = m_pos.y;
971
972 MIRROR( m_pos.y, aCenter );
973 m_pos.y -= m_size.y;
974 dy -= m_pos.y; // 0,dy is the move vector for this transform
975
976 for( SCH_SHEET_PIN* sheetPin : m_pins )
977 sheetPin->MirrorVertically( aCenter );
978
979 for( SCH_FIELD& field : m_fields )
980 {
981 VECTOR2I pos = field.GetTextPos();
982 pos.y -= dy;
983 field.SetTextPos( pos );
984 }
985}
986
987
989{
990 int dx = m_pos.x;
991
992 MIRROR( m_pos.x, aCenter );
993 m_pos.x -= m_size.x;
994 dx -= m_pos.x; // dx,0 is the move vector for this transform
995
996 for( SCH_SHEET_PIN* sheetPin : m_pins )
997 sheetPin->MirrorHorizontally( aCenter );
998
999 for( SCH_FIELD& field : m_fields )
1000 {
1001 VECTOR2I pos = field.GetTextPos();
1002 pos.x -= dx;
1003 field.SetTextPos( pos );
1004 }
1005}
1006
1007
1008void SCH_SHEET::SetPosition( const VECTOR2I& aPosition )
1009{
1010 // Remember the sheet and all pin sheet positions must be
1011 // modified. So use Move function to do that.
1012 Move( aPosition - m_pos );
1013}
1014
1015
1016void SCH_SHEET::Resize( const VECTOR2I& aSize )
1017{
1018 if( aSize == m_size )
1019 return;
1020
1021 m_size = aSize;
1022
1023 // Move the fields if we're in autoplace mode
1026
1027 // Move the sheet labels according to the new sheet size.
1028 for( SCH_SHEET_PIN* sheetPin : m_pins )
1029 sheetPin->ConstrainOnEdge( sheetPin->GetPosition(), false );
1030}
1031
1032
1033bool SCH_SHEET::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
1034{
1035 // Sheets are searchable via the child field and pin item text.
1036 return false;
1037}
1038
1039
1041{
1042 int id = 2;
1043
1044 for( SCH_SHEET_PIN* pin : m_pins )
1045 {
1046 pin->SetNumber( id );
1047 id++;
1048 }
1049}
1050
1051
1053{
1054 wxCHECK_MSG( Schematic(), SCH_SHEET_PATH(), "Can't call findSelf without a schematic" );
1055
1056 SCH_SHEET_PATH sheetPath = Schematic()->CurrentSheet();
1057
1058 while( !sheetPath.empty() && sheetPath.Last() != this )
1059 sheetPath.pop_back();
1060
1061 if( sheetPath.empty() )
1062 {
1063 // If we weren't in the hierarchy, then we must be a child of the current sheet.
1064 sheetPath = Schematic()->CurrentSheet();
1065 sheetPath.push_back( const_cast<SCH_SHEET*>( this ) );
1066 }
1067
1068 return sheetPath;
1069}
1070
1071
1072void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1073{
1074 for( SCH_SHEET_PIN* sheetPin : m_pins )
1075 {
1076 wxCHECK2_MSG( sheetPin->Type() == SCH_SHEET_PIN_T, continue,
1077 wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
1078
1079 sheetPin->GetEndPoints( aItemList );
1080 }
1081}
1082
1083
1084bool SCH_SHEET::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1085 std::vector<DANGLING_END_ITEM>& aItemListByPos,
1086 const SCH_SHEET_PATH* aPath )
1087{
1088 bool changed = false;
1089
1090 for( SCH_SHEET_PIN* sheetPin : m_pins )
1091 changed |= sheetPin->UpdateDanglingState( aItemListByType, aItemListByPos );
1092
1093 return changed;
1094}
1095
1096
1098 const SCH_SHEET_PATH* aInstance ) const
1099{
1100 // Do not compare to ourself.
1101 if( aItem == this )
1102 return false;
1103
1104 const SCH_SHEET* sheet = dynamic_cast<const SCH_SHEET*>( aItem );
1105
1106 // Don't compare against a different SCH_ITEM.
1107 wxCHECK( sheet, false );
1108
1109 if( GetPosition() != sheet->GetPosition() )
1110 return true;
1111
1112 // Technically this cannot happen because undo/redo does not support reloading sheet
1113 // file association changes. This was just added so that it doesn't get missed should
1114 // we ever fix the undo/redo issue.
1115 if( ( GetFileName() != sheet->GetFileName() ) || ( GetName() != sheet->GetName() ) )
1116 return true;
1117
1118 if( m_pins.size() != sheet->m_pins.size() )
1119 return true;
1120
1121 for( size_t i = 0; i < m_pins.size(); i++ )
1122 {
1123 if( m_pins[i]->HasConnectivityChanges( sheet->m_pins[i] ) )
1124 return true;
1125 }
1126
1127 return false;
1128}
1129
1130
1131std::vector<VECTOR2I> SCH_SHEET::GetConnectionPoints() const
1132{
1133 std::vector<VECTOR2I> retval;
1134
1135 for( SCH_SHEET_PIN* sheetPin : m_pins )
1136 retval.push_back( sheetPin->GetPosition() );
1137
1138 return retval;
1139}
1140
1141
1142INSPECT_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData,
1143 const std::vector<KICAD_T>& aScanTypes )
1144{
1145 for( KICAD_T scanType : aScanTypes )
1146 {
1147 // If caller wants to inspect my type
1148 if( scanType == SCH_LOCATE_ANY_T || scanType == Type() )
1149 {
1150 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1151 return INSPECT_RESULT::QUIT;
1152 }
1153
1154 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1155 {
1156 // Test the sheet fields.
1157 for( SCH_FIELD& field : m_fields )
1158 {
1159 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1160 return INSPECT_RESULT::QUIT;
1161 }
1162 }
1163
1164 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_SHEET_PIN_T )
1165 {
1166 // Test the sheet labels.
1167 for( SCH_SHEET_PIN* sheetPin : m_pins )
1168 {
1169 if( INSPECT_RESULT::QUIT == aInspector( sheetPin, this ) )
1170 return INSPECT_RESULT::QUIT;
1171 }
1172 }
1173 }
1174
1176}
1177
1178
1179void SCH_SHEET::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
1180{
1181 for( SCH_FIELD& field : m_fields )
1182 aFunction( &field );
1183
1184 for( SCH_SHEET_PIN* pin : m_pins )
1185 aFunction( pin );
1186}
1187
1188
1189wxString SCH_SHEET::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1190{
1191 const SCH_FIELD* sheetnameField = GetField( FIELD_T::SHEET_NAME );
1192
1193 return wxString::Format( _( "Hierarchical Sheet '%s'" ),
1194 aFull ? sheetnameField->GetShownText( false )
1195 : KIUI::EllipsizeMenuText( sheetnameField->GetText() ) );
1196}
1197
1198
1203
1204
1205bool SCH_SHEET::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1206{
1207 BOX2I rect = GetBodyBoundingBox();
1208
1209 rect.Inflate( aAccuracy );
1210
1211 return rect.Contains( aPosition );
1212}
1213
1214
1215bool SCH_SHEET::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1216{
1217 BOX2I rect = aRect;
1218
1219 rect.Inflate( aAccuracy );
1220
1221 if( aContained )
1222 return rect.Contains( GetBodyBoundingBox() );
1223
1224 return rect.Intersects( GetBodyBoundingBox() );
1225}
1226
1227
1228bool SCH_SHEET::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1229{
1230 return KIGEOM::BoxHitTest( aPoly, GetBodyBoundingBox(), aContained );
1231}
1232
1233
1234void SCH_SHEET::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1235 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1236{
1237 if( aBackground && !aPlotter->GetColorMode() )
1238 return;
1239
1240 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1241 COLOR4D borderColor = GetBorderColor();
1242 COLOR4D backgroundColor = GetBackgroundColor();
1243
1244 if( renderSettings->m_OverrideItemColors || borderColor == COLOR4D::UNSPECIFIED )
1245 borderColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET );
1246
1247 if( renderSettings->m_OverrideItemColors || backgroundColor == COLOR4D::UNSPECIFIED )
1248 backgroundColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET_BACKGROUND );
1249
1250 if( aBackground && backgroundColor.a > 0.0 )
1251 {
1252 aPlotter->SetColor( backgroundColor );
1253 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::FILLED_SHAPE, 1, 0 );
1254 }
1255 else
1256 {
1257 aPlotter->SetColor( borderColor );
1258
1259 int penWidth = GetEffectivePenWidth( getRenderSettings( aPlotter ) );
1260 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::NO_FILL, penWidth, 0 );
1261 }
1262
1263 // Make the sheet object a clickable hyperlink (e.g. for PDF plotter)
1264 if( aPlotOpts.m_PDFHierarchicalLinks )
1265 {
1266 aPlotter->HyperlinkBox( GetBoundingBox(),
1267 EDA_TEXT::GotoPageHref( findSelf().GetPageNumber() ) );
1268 }
1269 else if( aPlotOpts.m_PDFPropertyPopups )
1270 {
1271 std::vector<wxString> properties;
1272
1273 properties.emplace_back( EDA_TEXT::GotoPageHref( findSelf().GetPageNumber() ) );
1274
1275 for( const SCH_FIELD& field : GetFields() )
1276 {
1277 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), field.GetName(),
1278 field.GetShownText( false ) ) );
1279 }
1280
1281 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
1282 }
1283
1284 // Plot sheet pins
1285 for( SCH_SHEET_PIN* sheetPin : m_pins )
1286 sheetPin->Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1287
1288 // Plot the fields
1289 for( SCH_FIELD& field : m_fields )
1290 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1291
1292 if( GetDNP() )
1293 {
1295 BOX2I bbox = GetBodyBoundingBox();
1296 BOX2I pins = GetBoundingBox();
1297 VECTOR2D margins( std::max( bbox.GetX() - pins.GetX(),
1298 pins.GetEnd().x - bbox.GetEnd().x ),
1299 std::max( bbox.GetY() - pins.GetY(),
1300 pins.GetEnd().y - bbox.GetEnd().y ) );
1301 int strokeWidth = 3.0 * schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
1302
1303 margins.x = std::max( margins.x * 0.6, margins.y * 0.3 );
1304 margins.y = std::max( margins.y * 0.6, margins.x * 0.3 );
1305 bbox.Inflate( KiROUND( margins.x ), KiROUND( margins.y ) );
1306
1307 aPlotter->SetColor( colors->GetColor( LAYER_DNP_MARKER ) );
1308
1309 aPlotter->ThickSegment( bbox.GetOrigin(), bbox.GetEnd(), strokeWidth, nullptr );
1310
1311 aPlotter->ThickSegment( bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
1312 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
1313 strokeWidth, nullptr );
1314 }
1315}
1316
1317
1319{
1320 wxCHECK_MSG( Type() == aItem.Type(), *this,
1321 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1322 GetClass() );
1323
1324 if( &aItem != this )
1325 {
1326 SCH_ITEM::operator=( aItem );
1327
1328 SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
1329
1330 m_pos = sheet->m_pos;
1331 m_size = sheet->m_size;
1332 m_fields = sheet->m_fields;
1333
1334 for( SCH_SHEET_PIN* pin : sheet->m_pins )
1335 {
1336 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
1337 m_pins.back()->SetParent( this );
1338 }
1339
1340 for( const SCH_SHEET_INSTANCE& instance : sheet->m_instances )
1341 m_instances.emplace_back( instance );
1342 }
1343
1344 return *this;
1345}
1346
1347
1348bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const
1349{
1350 if( Type() != aItem.Type() )
1351 return Type() < aItem.Type();
1352
1353 const SCH_SHEET* otherSheet = static_cast<const SCH_SHEET*>( &aItem );
1354
1355 if( GetName() != otherSheet->GetName() )
1356 return GetName() < otherSheet->GetName();
1357
1358 if( GetFileName() != otherSheet->GetFileName() )
1359 return GetFileName() < otherSheet->GetFileName();
1360
1361 return false;
1362}
1363
1364
1365void SCH_SHEET::RemoveInstance( const KIID_PATH& aInstancePath )
1366{
1367 // Search for an existing path and remove it if found (should not occur)
1368 // (search from back to avoid invalidating iterator on remove)
1369 for( int ii = m_instances.size() - 1; ii >= 0; --ii )
1370 {
1371 if( m_instances[ii].m_Path == aInstancePath )
1372 {
1373 wxLogTrace( traceSchSheetPaths, "Removing sheet instance:\n"
1374 " sheet path %s\n"
1375 " page %s, from project %s.",
1376 aInstancePath.AsString(),
1377 m_instances[ii].m_PageNumber,
1378 m_instances[ii].m_ProjectName );
1379
1380 m_instances.erase( m_instances.begin() + ii );
1381 }
1382 }
1383}
1384
1385
1387{
1388 SCH_SHEET_INSTANCE oldInstance;
1389
1390 if( getInstance( oldInstance, aInstance.m_Path ) )
1391 RemoveInstance( aInstance.m_Path );
1392
1393 m_instances.emplace_back( aInstance );
1394
1395}
1396
1397
1399{
1400 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1401 {
1402 // if aSheetPath is found, nothing to do:
1403 if( instance.m_Path == aPath )
1404 return false;
1405 }
1406
1407 wxLogTrace( traceSchSheetPaths, wxT( "Adding instance `%s` to sheet `%s`." ),
1408 aPath.AsString(),
1409 ( GetName().IsEmpty() ) ? wxString( wxT( "root" ) ) : GetName() );
1410
1411 SCH_SHEET_INSTANCE instance;
1412
1413 instance.m_Path = aPath;
1414
1415 // This entry does not exist: add it with an empty page number.
1416 m_instances.emplace_back( instance );
1417 return true;
1418}
1419
1420
1421bool SCH_SHEET::getInstance( SCH_SHEET_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
1422 bool aTestFromEnd ) const
1423{
1424 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1425 {
1426 if( !aTestFromEnd )
1427 {
1428 if( instance.m_Path == aSheetPath )
1429 {
1430 aInstance = instance;
1431 return true;
1432 }
1433 }
1434 else if( instance.m_Path.EndsWith( aSheetPath ) )
1435 {
1436 aInstance = instance;
1437 return true;
1438 }
1439 }
1440
1441 return false;
1442}
1443
1444
1446{
1447 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1448 {
1449 if( instance.m_Path.size() == 0 )
1450 return true;
1451 }
1452
1453 return false;
1454}
1455
1456
1458{
1459 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1460 {
1461 if( instance.m_Path.size() == 0 )
1462 return instance;
1463 }
1464
1465 wxFAIL;
1466
1468
1469 return dummy;
1470}
1471
1472
1473wxString SCH_SHEET::getPageNumber( const KIID_PATH& aParentPath ) const
1474{
1475 wxString pageNumber;
1476
1477 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1478 {
1479 if( instance.m_Path == aParentPath )
1480 {
1481 pageNumber = instance.m_PageNumber;
1482 break;
1483 }
1484 }
1485
1486 return pageNumber;
1487}
1488
1489
1490void SCH_SHEET::setPageNumber( const KIID_PATH& aPath, const wxString& aPageNumber )
1491{
1492 for( SCH_SHEET_INSTANCE& instance : m_instances )
1493 {
1494 if( instance.m_Path == aPath )
1495 {
1496 instance.m_PageNumber = aPageNumber;
1497 break;
1498 }
1499 }
1500}
1501
1502
1504{
1505 // Avoid self comparison.
1506 if( &aOther == this )
1507 return false;
1508
1509 // A difference in the instance data count implies a page numbering change.
1510 if( GetInstances().size() != aOther.GetInstances().size() )
1511 return true;
1512
1513 std::vector<SCH_SHEET_INSTANCE> instances = GetInstances();
1514 std::vector<SCH_SHEET_INSTANCE> otherInstances = aOther.GetInstances();
1515
1516 // Sorting may not be necessary but there is no guarantee that sheet
1517 // instance data will be in the correct KIID_PATH order. We should
1518 // probably use a std::map instead of a std::vector to store the sheet
1519 // instance data.
1520 std::sort( instances.begin(), instances.end(),
1521 []( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
1522 {
1523 if( aLhs.m_Path > aRhs.m_Path )
1524 return true;
1525
1526 return false;
1527 } );
1528 std::sort( otherInstances.begin(), otherInstances.end(),
1529 []( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
1530 {
1531 if( aLhs.m_Path > aRhs.m_Path )
1532 return true;
1533
1534 return false;
1535 } );
1536
1537 auto itThis = instances.begin();
1538 auto itOther = otherInstances.begin();
1539
1540 while( itThis != instances.end() )
1541 {
1542 if( ( itThis->m_Path == itOther->m_Path )
1543 && ( itThis->m_PageNumber != itOther->m_PageNumber ) )
1544 {
1545 return true;
1546 }
1547
1548 itThis++;
1549 itOther++;
1550 }
1551
1552 return false;
1553}
1554
1555
1556int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
1557{
1558 if( aPageNumberA == aPageNumberB )
1559 return 0; // A == B
1560
1561 // First sort numerically if the page numbers are integers
1562 long pageA, pageB;
1563 bool isIntegerPageA = aPageNumberA.ToLong( &pageA );
1564 bool isIntegerPageB = aPageNumberB.ToLong( &pageB );
1565
1566 if( isIntegerPageA && isIntegerPageB )
1567 {
1568 if( pageA < pageB )
1569 return -1; //A < B
1570 else
1571 return 1; // A > B
1572 }
1573
1574 // Numerical page numbers always before strings
1575 if( isIntegerPageA )
1576 return -1; //A < B
1577 else if( isIntegerPageB )
1578 return 1; // A > B
1579
1580 // If not numeric, then sort as strings using natural sort
1581 int result = StrNumCmp( aPageNumberA, aPageNumberB );
1582
1583 // Divide by zero bad.
1584 wxCHECK( result != 0, 0 );
1585
1587
1588 return result;
1589}
1590
1591
1592bool SCH_SHEET::operator==( const SCH_ITEM& aOther ) const
1593{
1594 if( Type() != aOther.Type() )
1595 return false;
1596
1597 const SCH_SHEET* other = static_cast<const SCH_SHEET*>( &aOther );
1598
1599 if( m_pos != other->m_pos )
1600 return false;
1601
1602 if( m_size != other->m_size )
1603 return false;
1604
1605 if( GetExcludedFromSim() != other->GetExcludedFromSim() )
1606 return false;
1607
1608 if( GetExcludedFromBOM() != other->GetExcludedFromBOM() )
1609 return false;
1610
1611 if( GetExcludedFromBoard() != other->GetExcludedFromBoard() )
1612 return false;
1613
1614 if( GetDNP() != other->GetDNP() )
1615 return false;
1616
1617 if( GetBorderColor() != other->GetBorderColor() )
1618 return false;
1619
1620 if( GetBackgroundColor() != other->GetBackgroundColor() )
1621 return false;
1622
1623 if( GetBorderWidth() != other->GetBorderWidth() )
1624 return false;
1625
1626 if( GetFields().size() != other->GetFields().size() )
1627 return false;
1628
1629 for( size_t i = 0; i < GetFields().size(); ++i )
1630 {
1631 if( !( GetFields()[i] == other->GetFields()[i] ) )
1632 return false;
1633 }
1634
1635 return true;
1636}
1637
1638
1639double SCH_SHEET::Similarity( const SCH_ITEM& aOther ) const
1640{
1641 if( Type() != aOther.Type() )
1642 return 0.0;
1643
1644 const SCH_SHEET* other = static_cast<const SCH_SHEET*>( &aOther );
1645
1646 if( m_screen->GetFileName() == other->m_screen->GetFileName() )
1647 return 1.0;
1648
1649 return 0.0;
1650}
1651
1652
1654{
1655 return GetDNP( nullptr, Schematic()->GetCurrentVariant() );
1656}
1657
1658
1659void SCH_SHEET::SetDNPProp( bool aEnable )
1660{
1661 SetDNP( aEnable, nullptr, Schematic()->GetCurrentVariant() );
1662}
1663
1664
1666{
1667 return GetExcludedFromSim( nullptr, Schematic()->GetCurrentVariant() );
1668}
1669
1670
1672{
1673 SetExcludedFromSim( aEnable, nullptr, Schematic()->GetCurrentVariant() );
1674}
1675
1676
1678{
1679 return GetExcludedFromBOM( nullptr, Schematic()->GetCurrentVariant() );
1680}
1681
1682
1684{
1685 SetExcludedFromBOM( aEnable, nullptr, Schematic()->GetCurrentVariant() );
1686}
1687
1688
1689#if defined(DEBUG)
1690
1691void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
1692{
1693 // XML output:
1694 wxString s = GetClass();
1695
1696 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
1697 << TO_UTF8( GetName() ) << '"' << ">\n";
1698
1699 // show all the pins, and check the linked list integrity
1700 for( SCH_SHEET_PIN* sheetPin : m_pins )
1701 sheetPin->Show( nestLevel + 1, os );
1702
1703 NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
1704}
1705
1706#endif
1707
1708static struct SCH_SHEET_DESC
1709{
1711 {
1715
1716 propMgr.AddProperty( new PROPERTY<SCH_SHEET, wxString>( _HKI( "Sheet Name" ),
1718 .SetValidator( []( const wxAny&& aValue, EDA_ITEM* ) -> VALIDATOR_RESULT
1719 {
1720 wxString value;
1721
1722 if( !aValue.GetAs( &value ) )
1723 return {};
1724
1725 wxString msg = GetFieldValidationErrorMessage( FIELD_T::SHEET_NAME, value );
1726
1727 if( msg.empty() )
1728 return {};
1729
1730 return std::make_unique<VALIDATION_ERROR_MSG>( msg );
1731 } );
1732
1733 propMgr.AddProperty( new PROPERTY<SCH_SHEET, int>( _HKI( "Border Width" ),
1736
1737 propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Border Color" ),
1739
1740 propMgr.AddProperty( new PROPERTY<SCH_SHEET, COLOR4D>( _HKI( "Background Color" ),
1742
1743 const wxString groupAttributes = _HKI( "Attributes" );
1744
1745 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Board" ),
1747 groupAttributes );
1748 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Simulation" ),
1750 groupAttributes );
1751 propMgr.AddProperty(
1752 new PROPERTY<SCH_SHEET, bool>( _HKI( "Exclude From Bill of Materials" ),
1755 groupAttributes );
1756 propMgr.AddProperty( new PROPERTY<SCH_SHEET, bool>( _HKI( "Do not Populate" ),
1758 groupAttributes );
1759 }
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
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:398
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
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:98
const KIID m_Uuid
Definition eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
EDA_ITEM * GetParent() const
Definition eda_item.h:112
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:39
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:589
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:428
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:310
VECTOR2I GetTextSize() const
Definition eda_text.h:261
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:420
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
double a
Alpha component.
Definition color4d.h:395
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString AsString() const
Definition kiid.cpp:356
Definition kiid.h:49
Base plotter engine class.
Definition plotter.h:121
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:152
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:460
bool GetColorMode() const
Definition plotter.h:149
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition plotter.cpp:539
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition plotter.h:471
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:88
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
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:103
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
void GetContextualTextVars(wxArrayString *aVars) const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:186
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Schematic editor (Eeschema) main window.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:75
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:702
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:244
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition sch_item.h:757
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:51
wxString GetClass() const override
Return the class name.
Definition sch_item.h:177
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:647
SCH_LAYER_ID m_layer
Definition sch_item.h:753
const wxString & GetFileName() const
Definition sch_screen.h:152
bool GetExcludedFromBOM() const
bool empty() const
Forwarded method from std::vector.
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
wxString GetPageNumber() const
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:47
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:529
bool GetExcludedFromBoard() const override
Definition sch_sheet.h:441
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition sch_sheet.h:125
friend class SCH_SHEET_PIN
Definition sch_sheet.h:595
VECTOR2I m_size
Definition sch_sheet.h:612
void SetExcludedFromBoard(bool aExcludeFromBoard) override
Set or clear exclude from board netlist flag.
Definition sch_sheet.h:440
void SetFileName(const wxString &aFilename)
Definition sch_sheet.h:347
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:341
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.
Definition sch_sheet.h:404
void RemoveInstance(const KIID_PATH &aInstancePath)
void SetDNP(bool aDNP, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Definition sch_sheet.h:448
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.
Definition sch_sheet.h:422
int GetPenWidth() const override
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.
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:611
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:614
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
bool m_excludedFromBOM
Definition sch_sheet.h:607
wxString GetName() const
Definition sch_sheet.h:113
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
Definition sch_sheet.h:428
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
Definition sch_sheet.h:410
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:617
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
bool m_excludedFromSim
Definition sch_sheet.h:606
void SetPosition(const VECTOR2I &aPosition) override
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition sch_sheet.h:128
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:599
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:604
KIGFX::COLOR4D m_backgroundColor
Definition sch_sheet.h:615
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:54
void SetName(const wxString &aName)
Definition sch_sheet.h:114
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:463
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 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.
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:608
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:124
std::vector< SCH_SHEET_PIN * > m_pins
Definition sch_sheet.h:603
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:122
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
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.
Definition sch_sheet.h:446
bool GetExcludedFromSimProp() const
int m_borderWidth
Definition sch_sheet.h:613
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.
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:121
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:609
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.
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:478
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:127
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...
#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:50
INSPECT_RESULT
Definition eda_item.h:44
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:91
@ NO_FILL
Definition eda_shape.h:57
@ FILLED_SHAPE
Fill with object color.
Definition eda_shape.h:58
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:477
@ LAYER_SHEETNAME
Definition layer_ids.h:472
@ LAYER_SHEET_BACKGROUND
Definition layer_ids.h:485
@ LAYER_HIERLABEL
Definition layer_ids.h:457
@ LAYER_SHEETFIELDS
Definition layer_ids.h:474
@ LAYER_SHEET
Definition layer_ids.h:471
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:495
@ LAYER_SHEETFILENAME
Definition layer_ids.h:473
@ LAYER_DNP_MARKER
Definition layer_ids.h:478
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
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:362
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition sch_field.h:351
AUTOPLACE_ALGO
Definition sch_item.h:68
@ AUTOPLACE_MANUAL
Definition sch_item.h:71
@ AUTOPLACE_AUTO
Definition sch_item.h:70
int bumpToNextGrid(const int aVal, const int aDirection)
static struct SCH_SHEET_DESC _SCH_SHEET_DESC
#define MIN_SHEET_HEIGHT
Definition sch_sheet.h:40
#define MIN_SHEET_WIDTH
Definition sch_sheet.h:39
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.
#define DEFAULT_THEME
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
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.
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...
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:78
@ SCH_SYMBOL_T
Definition typeinfo.h:176
@ SCH_FIELD_T
Definition typeinfo.h:154
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:203
@ SCH_SHEET_T
Definition typeinfo.h:179
@ SCH_HIER_LABEL_T
Definition typeinfo.h:173
@ SCH_SHEET_PIN_T
Definition typeinfo.h:178
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:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694