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