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) 1992-2023 Kicad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <cstdlib>
26
27#include <bitmaps.h>
28#include <core/mirror.h>
29#include <core/kicad_algo.h>
30#include <sch_draw_panel.h>
31#include <trigo.h>
32#include <sch_edit_frame.h>
33#include <plotters/plotter.h>
34#include <string_utils.h>
35#include <widgets/msgpanel.h>
36#include <math/util.h> // for KiROUND
37#include <sch_sheet.h>
38#include <sch_sheet_path.h>
39#include <sch_sheet_pin.h>
40#include <sch_symbol.h>
41#include <sch_painter.h>
42#include <schematic.h>
44#include <trace_helpers.h>
45#include <pgm_base.h>
46#include <wx/log.h>
47
48// N.B. Do not change these values without transitioning the file format
49#define SHEET_NAME_CANONICAL "Sheetname"
50#define SHEET_FILE_CANONICAL "Sheetfile"
51#define USER_FIELD_CANONICAL "Field%d"
52
53
54const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx, bool aTranslated )
55{
56 if( !aTranslated )
57 {
58 switch( aFieldNdx )
59 {
62 default: return wxString::Format( USER_FIELD_CANONICAL, aFieldNdx );
63 }
64 }
65
66 // Fixed values for the mandatory fields
67 switch( aFieldNdx )
68 {
69 case SHEETNAME: return _( SHEET_NAME_CANONICAL );
70 case SHEETFILENAME: return _( SHEET_FILE_CANONICAL );
71 default: return wxString::Format( _( USER_FIELD_CANONICAL ), aFieldNdx );
72 }
73}
74
75
76SCH_SHEET::SCH_SHEET( EDA_ITEM* aParent, const VECTOR2I& aPos, VECTOR2I aSize,
77 FIELDS_AUTOPLACED aAutoplaceFields ) :
78 SCH_ITEM( aParent, SCH_SHEET_T )
79{
81 m_pos = aPos;
82 m_size = aSize;
83 m_screen = nullptr;
84
85 for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
86 {
87 m_fields.emplace_back( aPos, i, this, GetDefaultFieldName( i ) );
88 m_fields.back().SetVisible( true );
89
90 if( i == SHEETNAME )
91 m_fields.back().SetLayer( LAYER_SHEETNAME );
92 else if( i == SHEETFILENAME )
93 m_fields.back().SetLayer( LAYER_SHEETFILENAME );
94 else
95 m_fields.back().SetLayer( LAYER_SHEETFIELDS );
96 }
97
98 m_fieldsAutoplaced = aAutoplaceFields;
99 AutoAutoplaceFields( nullptr );
100
101 m_borderWidth = 0;
102 m_borderColor = COLOR4D::UNSPECIFIED;
103 m_backgroundColor = COLOR4D::UNSPECIFIED;
104}
105
106
108 SCH_ITEM( aSheet )
109{
110 m_pos = aSheet.m_pos;
111 m_size = aSheet.m_size;
112 m_layer = aSheet.m_layer;
113 const_cast<KIID&>( m_Uuid ) = aSheet.m_Uuid;
114 m_fields = aSheet.m_fields;
116 m_screen = aSheet.m_screen;
117
118 for( SCH_SHEET_PIN* pin : aSheet.m_pins )
119 {
120 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
121 m_pins.back()->SetParent( this );
122 }
123
124 for( SCH_FIELD& field : m_fields )
125 field.SetParent( this );
126
130 m_instances = aSheet.m_instances;
131
132 if( m_screen )
134}
135
136
138{
139 // also, look at the associated sheet & its reference count
140 // perhaps it should be deleted also.
141 if( m_screen )
142 {
144
145 if( m_screen->GetRefCount() == 0 )
146 delete m_screen;
147 }
148
149 // We own our pins; delete them
150 for( SCH_SHEET_PIN* pin : m_pins )
151 delete pin;
152}
153
154
156{
157 return new SCH_SHEET( *this );
158}
159
160
162{
163 if( aScreen == m_screen )
164 return;
165
166 if( m_screen != nullptr )
167 {
169
170 if( m_screen->GetRefCount() == 0 )
171 {
172 delete m_screen;
173 m_screen = nullptr;
174 }
175 }
176
177 m_screen = aScreen;
178
179 if( m_screen )
181}
182
183
185{
186 if( m_screen == nullptr )
187 return 0;
188
189 return m_screen->GetRefCount();
190}
191
192
194{
195 wxCHECK_MSG( Schematic(), false, "Can't call IsRootSheet without setting a schematic" );
196
197 return &Schematic()->Root() == this;
198}
199
200
201void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
202{
203 auto add =
204 [&]( const wxString& aVar )
205 {
206 if( !alg::contains( *aVars, aVar ) )
207 aVars->push_back( aVar );
208 };
209
210 for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
211 add( m_fields[i].GetCanonicalName().Upper() );
212
213 for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
214 add( m_fields[i].GetName() );
215
216 SCH_SHEET_PATH sheetPath = findSelf();
217
218 if( sheetPath.size() >= 2 )
219 {
220 sheetPath.pop_back();
221 sheetPath.Last()->GetContextualTextVars( aVars );
222 }
223 else if( Schematic() )
224 {
226 }
227
228 add( wxT( "#" ) );
229 add( wxT( "##" ) );
230 add( wxT( "SHEETPATH" ) );
231
233}
234
235
236bool SCH_SHEET::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
237{
238 if( !Schematic() )
239 return false;
240
241 if( token->Contains( ':' ) )
242 {
243 if( Schematic()->ResolveCrossReference( token, aDepth + 1 ) )
244 return true;
245 }
246
247 for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
248 {
249 if( token->IsSameAs( m_fields[i].GetCanonicalName().Upper() ) )
250 {
251 *token = m_fields[i].GetShownText( nullptr, false, aDepth + 1 );
252 return true;
253 }
254 }
255
256 for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
257 {
258 if( token->IsSameAs( m_fields[i].GetName() ) )
259 {
260 *token = m_fields[i].GetShownText( nullptr, false, aDepth + 1 );
261 return true;
262 }
263 }
264
265 PROJECT *project = &Schematic()->Prj();
266
267 // We cannot resolve text variables initially on load as we need to first load the screen and
268 // then parse the hierarchy. So skip the resolution if the screen isn't set yet
270 {
271 return true;
272 }
273
274 if( token->IsSameAs( wxT( "#" ) ) )
275 {
276 *token = wxString::Format( "%s", findSelf().GetPageNumber() );
277 return true;
278 }
279 else if( token->IsSameAs( wxT( "##" ) ) )
280 {
281 SCH_SHEET_LIST sheetList = Schematic()->GetSheets();
282 *token = wxString::Format( wxT( "%d" ), (int) sheetList.size() );
283 return true;
284 }
285 else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
286 {
287 *token = findSelf().PathHumanReadable();
288 return true;
289 }
290
291 // See if parent can resolve it (these will recurse to ancestors)
292
293 SCH_SHEET_PATH sheetPath = aPath ? *aPath : findSelf();
294
295 if( sheetPath.size() >= 2 )
296 {
297 sheetPath.pop_back();
298
299 if( sheetPath.Last()->ResolveTextVar( &sheetPath, token, aDepth + 1 ) )
300 return true;
301 }
302 else
303 {
304 if( Schematic()->ResolveTextVar( token, aDepth + 1 ) )
305 return true;
306 }
307
308 return false;
309}
310
311
313{
314 wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
315 wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
316 aItem->GetClass() ) );
317
318 SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
319
320 std::swap( m_pos, sheet->m_pos );
321 std::swap( m_size, sheet->m_size );
322 m_fields.swap( sheet->m_fields );
323 std::swap( m_fieldsAutoplaced, sheet->m_fieldsAutoplaced );
324 m_pins.swap( sheet->m_pins );
325
326 // Update parent pointers after swapping.
327 for( SCH_SHEET_PIN* sheetPin : m_pins )
328 sheetPin->SetParent( this );
329
330 for( SCH_SHEET_PIN* sheetPin : sheet->m_pins )
331 sheetPin->SetParent( sheet );
332
333 for( SCH_FIELD& field : m_fields )
334 field.SetParent( this );
335
336 for( SCH_FIELD& field : sheet->m_fields )
337 field.SetParent( sheet );
338
339 std::swap( m_borderWidth, sheet->m_borderWidth );
340 std::swap( m_borderColor, sheet->m_borderColor );
341 std::swap( m_backgroundColor, sheet->m_backgroundColor );
342 std::swap( m_instances, sheet->m_instances );
343}
344
345
346void SCH_SHEET::SetFields( const std::vector<SCH_FIELD>& aFields )
347{
348 m_fields = aFields;
349 int next_id = SHEET_MANDATORY_FIELDS;
350
351 for( int ii = 0; ii < int( m_fields.size() ); )
352 {
353 if( m_fields[ii].GetId() < 0 || m_fields[ii].GetId() >= ssize_t( m_fields.size() ) )
354 m_fields[ii].SetId( next_id++ );
355
356 if( m_fields[ii].GetId() != ii )
357 std::swap( m_fields[ii], m_fields[m_fields[ii].GetId()]);
358
359 if( m_fields[ii].GetId() == ii )
360 ++ii;
361 }
362
363 // Make sure that we get the UNIX variant of the file path
364 SetFileName( m_fields[SHEETFILENAME].GetText() );
365}
366
367
369{
370 wxASSERT( aSheetPin != nullptr );
371 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
372
373 aSheetPin->SetParent( this );
374 m_pins.push_back( aSheetPin );
375 renumberPins();
376}
377
378
379void SCH_SHEET::RemovePin( const SCH_SHEET_PIN* aSheetPin )
380{
381 wxASSERT( aSheetPin != nullptr );
382 wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
383
384 for( auto i = m_pins.begin(); i < m_pins.end(); ++i )
385 {
386 if( *i == aSheetPin )
387 {
388 m_pins.erase( i );
389 renumberPins();
390 return;
391 }
392 }
393}
394
395
396bool SCH_SHEET::HasPin( const wxString& aName ) const
397{
398 for( SCH_SHEET_PIN* pin : m_pins )
399 {
400 if( pin->GetText().Cmp( aName ) == 0 )
401 return true;
402 }
403
404 return false;
405}
406
407
408bool SCH_SHEET::doIsConnected( const VECTOR2I& aPosition ) const
409{
410 for( SCH_SHEET_PIN* sheetPin : m_pins )
411 {
412 if( sheetPin->GetPosition() == aPosition )
413 return true;
414 }
415
416 return false;
417}
418
419
421{
422 int leftRight = 0;
423 int topBottom = 0;
424
425 for( SCH_SHEET_PIN* pin : m_pins )
426 {
427 switch( pin->GetSide() )
428 {
429 case SHEET_SIDE::LEFT: leftRight++; break;
430 case SHEET_SIDE::RIGHT: leftRight++; break;
431 case SHEET_SIDE::TOP: topBottom++; break;
432 case SHEET_SIDE::BOTTOM: topBottom++; break;
433 default: break;
434 }
435 }
436
437 return topBottom > 0 && leftRight == 0;
438}
439
440
442{
443 for( SCH_SHEET_PIN* pin : m_pins )
444 {
445 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
446 const SCH_HIERLABEL* HLabel = nullptr;
447
448 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
449 {
450 if( !pin->GetText().Cmp( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
451 {
452 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
453 break;
454 }
455 }
456
457 if( HLabel == nullptr ) // Corresponding hierarchical label not found.
458 return true;
459 }
460
461 return false;
462}
463
464
465int bumpToNextGrid( const int aVal, const int aDirection )
466{
467 constexpr int gridSize = schIUScale.MilsToIU( 50 );
468
469 int base = aVal / gridSize;
470 int excess = abs( aVal % gridSize );
471
472 if( aDirection > 0 )
473 {
474 return ( base + 1 ) * gridSize;
475 }
476 else if( excess > 0 )
477 {
478 return ( base ) * gridSize;
479 }
480 else
481 {
482 return ( base - 1 ) * gridSize;
483 }
484}
485
486
487int SCH_SHEET::GetMinWidth( bool aFromLeft ) const
488{
489 int pinsLeft = m_pos.x + m_size.x;
490 int pinsRight = m_pos.x;
491
492 for( size_t i = 0; i < m_pins.size(); i++ )
493 {
494 SHEET_SIDE edge = m_pins[i]->GetSide();
495
496 if( edge == SHEET_SIDE::TOP || edge == SHEET_SIDE::BOTTOM )
497 {
498 BOX2I pinRect = m_pins[i]->GetBoundingBox();
499
500 pinsLeft = std::min( pinsLeft, pinRect.GetLeft() );
501 pinsRight = std::max( pinsRight, pinRect.GetRight() );
502 }
503 }
504
505 pinsLeft = bumpToNextGrid( pinsLeft, -1 );
506 pinsRight = bumpToNextGrid( pinsRight, 1 );
507
508 int pinMinWidth;
509
510 if( pinsLeft >= pinsRight )
511 pinMinWidth = 0;
512 else if( aFromLeft )
513 pinMinWidth = pinsRight - m_pos.x;
514 else
515 pinMinWidth = m_pos.x + m_size.x - pinsLeft;
516
517 return std::max( pinMinWidth, schIUScale.MilsToIU( MIN_SHEET_WIDTH ) );
518}
519
520
521int SCH_SHEET::GetMinHeight( bool aFromTop ) const
522{
523 int pinsTop = m_pos.y + m_size.y;
524 int pinsBottom = m_pos.y;
525
526 for( size_t i = 0; i < m_pins.size(); i++ )
527 {
528 SHEET_SIDE edge = m_pins[i]->GetSide();
529
530 if( edge == SHEET_SIDE::RIGHT || edge == SHEET_SIDE::LEFT )
531 {
532 BOX2I pinRect = m_pins[i]->GetBoundingBox();
533
534 pinsTop = std::min( pinsTop, pinRect.GetTop() );
535 pinsBottom = std::max( pinsBottom, pinRect.GetBottom() );
536 }
537 }
538
539 pinsTop = bumpToNextGrid( pinsTop, -1 );
540 pinsBottom = bumpToNextGrid( pinsBottom, 1 );
541
542 int pinMinHeight;
543
544 if( pinsTop >= pinsBottom )
545 pinMinHeight = 0;
546 else if( aFromTop )
547 pinMinHeight = pinsBottom - m_pos.y;
548 else
549 pinMinHeight = m_pos.y + m_size.y - pinsTop;
550
551 return std::max( pinMinHeight, schIUScale.MilsToIU( MIN_SHEET_HEIGHT ) );
552}
553
554
556{
557 std::vector<SCH_SHEET_PIN*> pins = m_pins;
558
559 m_pins.clear();
560
561 for( SCH_SHEET_PIN* pin : pins )
562 {
563 /* Search the schematic for a hierarchical label corresponding to this sheet label. */
564 const SCH_HIERLABEL* HLabel = nullptr;
565
566 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
567 {
568 if( pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) == 0 )
569 {
570 HLabel = static_cast<SCH_HIERLABEL*>( aItem );
571 break;
572 }
573 }
574
575 if( HLabel )
576 m_pins.push_back( pin );
577 }
578}
579
580
582{
583 for( SCH_SHEET_PIN* pin : m_pins )
584 {
585 if( pin->HitTest( aPosition ) )
586 return pin;
587 }
588
589 return nullptr;
590}
591
592
594{
595 if( GetBorderWidth() > 0 )
596 return GetBorderWidth();
597
598 if( Schematic() )
600
602}
603
604
605void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool /* aManual */ )
606{
607 VECTOR2I textSize = m_fields[SHEETNAME].GetTextSize();
608 int borderMargin = KiROUND( GetPenWidth() / 2.0 ) + 4;
609 int margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.5 );
610
612 {
613 m_fields[SHEETNAME].SetTextPos( m_pos + VECTOR2I( -margin, m_size.y ) );
614 m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
615 m_fields[ SHEETNAME ].SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
616 m_fields[ SHEETNAME ].SetTextAngle( ANGLE_VERTICAL );
617 }
618 else
619 {
620 m_fields[SHEETNAME].SetTextPos( m_pos + VECTOR2I( 0, -margin ) );
621 m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
622 m_fields[ SHEETNAME ].SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
623 m_fields[ SHEETNAME ].SetTextAngle( ANGLE_HORIZONTAL );
624 }
625
626 textSize = m_fields[ SHEETFILENAME ].GetTextSize();
627 margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.4 );
628
630 {
631 m_fields[SHEETFILENAME].SetTextPos( m_pos + VECTOR2I( m_size.x + margin, m_size.y ) );
632 m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
633 m_fields[ SHEETFILENAME ].SetVertJustify( GR_TEXT_V_ALIGN_TOP );
634 m_fields[ SHEETFILENAME ].SetTextAngle( ANGLE_VERTICAL );
635 }
636 else
637 {
638 m_fields[SHEETFILENAME].SetTextPos( m_pos + VECTOR2I( 0, m_size.y + margin ) );
639 m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
640 m_fields[ SHEETFILENAME ].SetVertJustify( GR_TEXT_V_ALIGN_TOP );
641 m_fields[ SHEETFILENAME ].SetTextAngle( ANGLE_HORIZONTAL );
642 }
643
645}
646
647
648void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const
649{
650 aCount = 7;
651 aLayers[0] = LAYER_HIERLABEL;
652 aLayers[1] = LAYER_SHEETNAME;
653 aLayers[2] = LAYER_SHEETFILENAME;
654 aLayers[3] = LAYER_SHEETFIELDS;
655 aLayers[4] = LAYER_SHEET;
656 aLayers[5] = LAYER_SHEET_BACKGROUND;
657 aLayers[6] = LAYER_SELECTION_SHADOWS;
658}
659
660
662{
663 VECTOR2I end;
664 BOX2I box( m_pos, m_size );
665 int lineWidth = GetPenWidth();
666 int textLength = 0;
667
668 // Calculate bounding box X size:
669 end.x = std::max( m_size.x, textLength );
670
671 // Calculate bounding box pos:
672 end.y = m_size.y;
673 end += m_pos;
674
675 box.SetEnd( end );
676 box.Inflate( lineWidth / 2 );
677
678 return box;
679}
680
681
683{
684 BOX2I bbox = GetBodyBoundingBox();
685
686 for( const SCH_FIELD& field : m_fields )
687 bbox.Merge( field.GetBoundingBox() );
688
689 return bbox;
690}
691
692
694{
695 BOX2I box( m_pos, m_size );
696 return box.GetCenter();
697}
698
699
701{
702 int n = 0;
703
704 if( m_screen )
705 {
706 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SYMBOL_T ) )
707 {
708 SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
709
710 if( symbol->GetField( VALUE_FIELD )->GetText().GetChar( 0 ) != '#' )
711 n++;
712 }
713
714 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
715 n += static_cast<const SCH_SHEET*>( aItem )->SymbolCount();
716 }
717
718 return n;
719}
720
721
722bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
723{
724 if( m_screen )
725 {
726 // Only check the root sheet once and don't recurse.
727 if( !GetParent() )
728 {
729 if( m_screen && m_screen->GetFileName().Cmp( aFilename ) == 0 )
730 {
731 *aScreen = m_screen;
732 return true;
733 }
734 }
735
736 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
737 {
738 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
739 SCH_SCREEN* screen = sheet->m_screen;
740
741 // Must use the screen's path (which is always absolute) rather than the
742 // sheet's (which could be relative).
743 if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
744 {
745 *aScreen = screen;
746 return true;
747 }
748
749 if( sheet->SearchHierarchy( aFilename, aScreen ) )
750 return true;
751 }
752 }
753
754 return false;
755}
756
757
759{
760 if( m_screen )
761 {
762 aList->push_back( this );
763
764 if( m_screen == aScreen )
765 return true;
766
767 for( EDA_ITEM* item : m_screen->Items().OfType( SCH_SHEET_T ) )
768 {
769 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
770
771 if( sheet->LocatePathOfScreen( aScreen, aList ) )
772 return true;
773 }
774
775 aList->pop_back();
776 }
777
778 return false;
779}
780
781
783{
784 int count = 1; //1 = this!!
785
786 if( m_screen )
787 {
788 for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
789 count += static_cast<SCH_SHEET*>( aItem )->CountSheets();
790 }
791
792 return count;
793}
794
795
796void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
797{
798 // Don't use GetShownText(); we want to see the variable references here
799 aList.emplace_back( _( "Sheet Name" ),
800 KIUI::EllipsizeStatusText( aFrame, m_fields[ SHEETNAME ].GetText() ) );
801
802 if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
803 {
804 SCH_SHEET_PATH path = schframe->GetCurrentSheet();
805 path.push_back( this );
806
807 aList.emplace_back( _( "Hierarchical Path" ), path.PathHumanReadable( false, true ) );
808 }
809
810 // Don't use GetShownText(); we want to see the variable references here
811 aList.emplace_back( _( "File Name" ),
812 KIUI::EllipsizeStatusText( aFrame, m_fields[ SHEETFILENAME ].GetText() ) );
813}
814
815
816void SCH_SHEET::Move( const VECTOR2I& aMoveVector )
817{
818 m_pos += aMoveVector;
819
820 for( SCH_SHEET_PIN* pin : m_pins )
821 pin->Move( aMoveVector );
822
823 for( SCH_FIELD& field : m_fields )
824 field.Move( aMoveVector );
825}
826
827
828void SCH_SHEET::Rotate( const VECTOR2I& aCenter )
829{
830 VECTOR2I prev = m_pos;
831
832 RotatePoint( m_pos, aCenter, ANGLE_90 );
834
835 if( m_size.x < 0 )
836 {
837 m_pos.x += m_size.x;
838 m_size.x = -m_size.x;
839 }
840
841 if( m_size.y < 0 )
842 {
843 m_pos.y += m_size.y;
844 m_size.y = -m_size.y;
845 }
846
847 // Pins must be rotated first as that's how we determine vertical vs horizontal
848 // orientation for auto-placement
849 for( SCH_SHEET_PIN* sheetPin : m_pins )
850 sheetPin->Rotate( aCenter );
851
853 {
854 AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
855 }
856 else
857 {
858 // Move the fields to the new position because the parent itself has moved.
859 for( SCH_FIELD& field : m_fields )
860 {
861 VECTOR2I pos = field.GetTextPos();
862 pos.x -= prev.x - m_pos.x;
863 pos.y -= prev.y - m_pos.y;
864 field.SetTextPos( pos );
865 }
866 }
867}
868
869
871{
872 int dy = m_pos.y;
873
874 MIRROR( m_pos.y, aCenter );
875 m_pos.y -= m_size.y;
876 dy -= m_pos.y; // 0,dy is the move vector for this transform
877
878 for( SCH_SHEET_PIN* sheetPin : m_pins )
879 sheetPin->MirrorVertically( aCenter );
880
881 for( SCH_FIELD& field : m_fields )
882 {
883 VECTOR2I pos = field.GetTextPos();
884 pos.y -= dy;
885 field.SetTextPos( pos );
886 }
887}
888
889
891{
892 int dx = m_pos.x;
893
894 MIRROR( m_pos.x, aCenter );
895 m_pos.x -= m_size.x;
896 dx -= m_pos.x; // dx,0 is the move vector for this transform
897
898 for( SCH_SHEET_PIN* sheetPin : m_pins )
899 sheetPin->MirrorHorizontally( aCenter );
900
901 for( SCH_FIELD& field : m_fields )
902 {
903 VECTOR2I pos = field.GetTextPos();
904 pos.x -= dx;
905 field.SetTextPos( pos );
906 }
907}
908
909
910void SCH_SHEET::SetPosition( const VECTOR2I& aPosition )
911{
912 // Remember the sheet and all pin sheet positions must be
913 // modified. So use Move function to do that.
914 Move( aPosition - m_pos );
915}
916
917
918void SCH_SHEET::Resize( const VECTOR2I& aSize )
919{
920 if( aSize == m_size )
921 return;
922
923 m_size = aSize;
924
925 // Move the fields if we're in autoplace mode
927 AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
928
929 // Move the sheet labels according to the new sheet size.
930 for( SCH_SHEET_PIN* sheetPin : m_pins )
931 sheetPin->ConstrainOnEdge( sheetPin->GetPosition() );
932}
933
934
935bool SCH_SHEET::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
936{
937 // Sheets are searchable via the child field and pin item text.
938 return false;
939}
940
941
943{
944 int id = 2;
945
946 for( SCH_SHEET_PIN* pin : m_pins )
947 {
948 pin->SetNumber( id );
949 id++;
950 }
951}
952
953
955{
956 wxCHECK_MSG( Schematic(), SCH_SHEET_PATH(), "Can't call findSelf without a schematic" );
957
958 SCH_SHEET_PATH sheetPath = Schematic()->CurrentSheet();
959
960 while( !sheetPath.empty() && sheetPath.Last() != this )
961 sheetPath.pop_back();
962
963 if( sheetPath.empty() )
964 {
965 // If we weren't in the hierarchy, then we must be a child of the current sheet.
966 sheetPath = Schematic()->CurrentSheet();
967 sheetPath.push_back( const_cast<SCH_SHEET*>( this ) );
968 }
969
970 return sheetPath;
971}
972
973
974void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
975{
976 for( SCH_SHEET_PIN* sheetPin : m_pins )
977 {
978 wxCHECK2_MSG( sheetPin->Type() == SCH_SHEET_PIN_T, continue,
979 wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
980
981 sheetPin->GetEndPoints( aItemList );
982 }
983}
984
985
986bool SCH_SHEET::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
987 const SCH_SHEET_PATH* aPath )
988{
989 bool changed = false;
990
991 for( SCH_SHEET_PIN* sheetPin : m_pins )
992 changed |= sheetPin->UpdateDanglingState( aItemList );
993
994 return changed;
995}
996
997
998std::vector<VECTOR2I> SCH_SHEET::GetConnectionPoints() const
999{
1000 std::vector<VECTOR2I> retval;
1001
1002 for( SCH_SHEET_PIN* sheetPin : m_pins )
1003 retval.push_back( sheetPin->GetPosition() );
1004
1005 return retval;
1006}
1007
1008
1009INSPECT_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData,
1010 const std::vector<KICAD_T>& aScanTypes )
1011{
1012 for( KICAD_T scanType : aScanTypes )
1013 {
1014 // If caller wants to inspect my type
1015 if( scanType == SCH_LOCATE_ANY_T || scanType == Type() )
1016 {
1017 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1018 return INSPECT_RESULT::QUIT;
1019 }
1020
1021 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1022 {
1023 // Test the sheet fields.
1024 for( SCH_FIELD& field : m_fields )
1025 {
1026 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1027 return INSPECT_RESULT::QUIT;
1028 }
1029 }
1030
1031 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_SHEET_PIN_T )
1032 {
1033 // Test the sheet labels.
1034 for( SCH_SHEET_PIN* sheetPin : m_pins )
1035 {
1036 if( INSPECT_RESULT::QUIT == aInspector( sheetPin, this ) )
1037 return INSPECT_RESULT::QUIT;
1038 }
1039 }
1040 }
1041
1042 return INSPECT_RESULT::CONTINUE;
1043}
1044
1045
1046void SCH_SHEET::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
1047{
1048 for( SCH_FIELD& field : m_fields )
1049 aFunction( &field );
1050
1051 for( SCH_SHEET_PIN* pin : m_pins )
1052 aFunction( pin );
1053}
1054
1055
1056wxString SCH_SHEET::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
1057{
1058 return wxString::Format( _( "Hierarchical Sheet %s" ),
1059 KIUI::EllipsizeMenuText( m_fields[ SHEETNAME ].GetText() ) );
1060}
1061
1062
1064{
1065 return BITMAPS::add_hierarchical_subsheet;
1066}
1067
1068
1069bool SCH_SHEET::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1070{
1071 BOX2I rect = GetBodyBoundingBox();
1072
1073 rect.Inflate( aAccuracy );
1074
1075 return rect.Contains( aPosition );
1076}
1077
1078
1079bool SCH_SHEET::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1080{
1081 BOX2I rect = aRect;
1082
1083 rect.Inflate( aAccuracy );
1084
1085 if( aContained )
1086 return rect.Contains( GetBodyBoundingBox() );
1087
1088 return rect.Intersects( GetBodyBoundingBox() );
1089}
1090
1091
1092void SCH_SHEET::Plot( PLOTTER* aPlotter, bool aBackground ) const
1093{
1094 if( aBackground && !aPlotter->GetColorMode() )
1095 return;
1096
1097 auto* settings = dynamic_cast<KIGFX::SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
1098 bool override = settings ? settings->m_OverrideItemColors : false;
1099 COLOR4D borderColor = GetBorderColor();
1100 COLOR4D backgroundColor = GetBackgroundColor();
1101
1102 if( override || borderColor == COLOR4D::UNSPECIFIED )
1103 borderColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET );
1104
1105 if( override || backgroundColor == COLOR4D::UNSPECIFIED )
1106 backgroundColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET_BACKGROUND );
1107
1108 if( aBackground )
1109 {
1110 aPlotter->SetColor( backgroundColor );
1111 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::FILLED_SHAPE, 1 );
1112 }
1113 else
1114 {
1115 aPlotter->SetColor( borderColor );
1116
1117 int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() );
1118 aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::NO_FILL, penWidth );
1119 }
1120
1121 // Make the sheet object a clickable hyperlink (e.g. for PDF plotter)
1122 std::vector<wxString> properties;
1123
1124 properties.emplace_back( EDA_TEXT::GotoPageHref( findSelf().GetPageNumber() ) );
1125
1126 for( const SCH_FIELD& field : GetFields() )
1127 {
1128 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
1129 field.GetName(),
1130 field.GetShownText( false ) ) );
1131 }
1132
1133 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
1134
1135 // Plot sheet pins
1136 for( SCH_SHEET_PIN* sheetPin : m_pins )
1137 sheetPin->Plot( aPlotter, aBackground );
1138
1139 // Plot the fields
1140 for( const SCH_FIELD& field : m_fields )
1141 field.Plot( aPlotter, aBackground );
1142}
1143
1144
1145void SCH_SHEET::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset )
1146{
1147 wxDC* DC = aSettings->GetPrintDC();
1148 VECTOR2I pos = m_pos + aOffset;
1149 int lineWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
1150 const auto* settings = dynamic_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
1151 bool override = settings && settings->m_OverrideItemColors;
1152 COLOR4D border = GetBorderColor();
1153 COLOR4D background = GetBackgroundColor();
1154
1155 if( override || border == COLOR4D::UNSPECIFIED )
1156 border = aSettings->GetLayerColor( LAYER_SHEET );
1157
1158 if( override || background == COLOR4D::UNSPECIFIED )
1159 background = aSettings->GetLayerColor( LAYER_SHEET_BACKGROUND );
1160
1161 if( GetGRForceBlackPenState() ) // printing in black & white
1162 background = COLOR4D::UNSPECIFIED;
1163
1164 if( background != COLOR4D::UNSPECIFIED )
1165 GRFilledRect( DC, pos, pos + m_size, 0, background, background );
1166
1167 GRRect( DC, pos, pos + m_size, lineWidth, border );
1168
1169 for( SCH_FIELD& field : m_fields )
1170 field.Print( aSettings, aOffset );
1171
1172 for( SCH_SHEET_PIN* sheetPin : m_pins )
1173 sheetPin->Print( aSettings, aOffset );
1174}
1175
1176
1178{
1179 wxCHECK_MSG( Type() == aItem.Type(), *this,
1180 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1181 GetClass() );
1182
1183 if( &aItem != this )
1184 {
1185 SCH_ITEM::operator=( aItem );
1186
1187 SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
1188
1189 m_pos = sheet->m_pos;
1190 m_size = sheet->m_size;
1191 m_fields = sheet->m_fields;
1192
1193 for( SCH_SHEET_PIN* pin : sheet->m_pins )
1194 {
1195 m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
1196 m_pins.back()->SetParent( this );
1197 }
1198
1199 for( const SCH_SHEET_INSTANCE& instance : sheet->m_instances )
1200 m_instances.emplace_back( instance );
1201 }
1202
1203 return *this;
1204}
1205
1206
1207bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const
1208{
1209 if( Type() != aItem.Type() )
1210 return Type() < aItem.Type();
1211
1212 auto sheet = static_cast<const SCH_SHEET*>( &aItem );
1213
1214 if (m_fields[ SHEETNAME ].GetText() != sheet->m_fields[ SHEETNAME ].GetText() )
1215 return m_fields[ SHEETNAME ].GetText() < sheet->m_fields[ SHEETNAME ].GetText();
1216
1217 if (m_fields[ SHEETFILENAME ].GetText() != sheet->m_fields[ SHEETFILENAME ].GetText() )
1218 return m_fields[ SHEETFILENAME ].GetText() < sheet->m_fields[ SHEETFILENAME ].GetText();
1219
1220 return false;
1221}
1222
1223
1225{
1226 wxCHECK( aSheetPath.IsFullPath(), false );
1227 wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), false );
1228
1229 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1230 {
1231 // if aSheetPath is found, nothing to do:
1232 if( instance.m_Path == aSheetPath.Path() )
1233 return false;
1234 }
1235
1236 wxLogTrace( traceSchSheetPaths, wxT( "Adding instance `%s` to sheet `%s`." ),
1237 aSheetPath.Path().AsString(),
1238 ( GetName().IsEmpty() ) ? wxString( wxT( "root" ) ) : GetName() );
1239
1240 SCH_SHEET_INSTANCE instance;
1241
1242 instance.m_Path = aSheetPath.Path();
1243
1244 // This entry does not exist: add it with an empty page number.
1245 m_instances.emplace_back( instance );
1246 return true;
1247}
1248
1249
1250bool SCH_SHEET::getInstance( SCH_SHEET_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
1251 bool aTestFromEnd ) const
1252{
1253 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1254 {
1255 if( !aTestFromEnd )
1256 {
1257 if( instance.m_Path == aSheetPath )
1258 {
1259 aInstance = instance;
1260 return true;
1261 }
1262 }
1263 else if( instance.m_Path.EndsWith( aSheetPath ) )
1264 {
1265 aInstance = instance;
1266 return true;
1267 }
1268 }
1269
1270 return false;
1271}
1272
1273
1275{
1276 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1277 {
1278 if( instance.m_Path.size() == 0 )
1279 return true;
1280 }
1281
1282 return false;
1283}
1284
1285
1287{
1288 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1289 {
1290 if( instance.m_Path.size() == 0 )
1291 return instance;
1292 }
1293
1294 wxFAIL;
1295
1297
1298 return dummy;
1299}
1300
1301
1302wxString SCH_SHEET::getPageNumber( const SCH_SHEET_PATH& aSheetPath ) const
1303{
1304 wxCHECK( aSheetPath.IsFullPath(), wxEmptyString );
1305 wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), wxEmptyString );
1306
1307 wxString pageNumber;
1308 KIID_PATH path = aSheetPath.Path();
1309
1310 for( const SCH_SHEET_INSTANCE& instance : m_instances )
1311 {
1312 if( instance.m_Path == path )
1313 {
1314 pageNumber = instance.m_PageNumber;
1315 break;
1316 }
1317 }
1318
1319 return pageNumber;
1320}
1321
1322
1323void SCH_SHEET::setPageNumber( const SCH_SHEET_PATH& aSheetPath, const wxString& aPageNumber )
1324{
1325 wxCHECK( aSheetPath.IsFullPath(), /* void */ );
1326 wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), /* void */ );
1327
1328 KIID_PATH path = aSheetPath.Path();
1329
1330 for( SCH_SHEET_INSTANCE& instance : m_instances )
1331 {
1332 if( instance.m_Path == path )
1333 {
1334 instance.m_PageNumber = aPageNumber;
1335 break;
1336 }
1337 }
1338}
1339
1340
1341int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
1342{
1343 if( aPageNumberA == aPageNumberB )
1344 return 0; // A == B
1345
1346 // First sort numerically if the page numbers are integers
1347 long pageA, pageB;
1348 bool isIntegerPageA = aPageNumberA.ToLong( &pageA );
1349 bool isIntegerPageB = aPageNumberB.ToLong( &pageB );
1350
1351 if( isIntegerPageA && isIntegerPageB )
1352 {
1353 if( pageA < pageB )
1354 return -1; //A < B
1355 else
1356 return 1; // A > B
1357 }
1358
1359 // Numerical page numbers always before strings
1360 if( isIntegerPageA )
1361 return -1; //A < B
1362 else if( isIntegerPageB )
1363 return 1; // A > B
1364
1365 // If not numeric, then sort as strings using natural sort
1366 int result = StrNumCmp( aPageNumberA, aPageNumberB );
1367
1368 // Divide by zero bad.
1369 wxCHECK( result != 0, 0 );
1370
1371 result = result / std::abs( result );
1372
1373 return result;
1374}
1375
1376
1377#if defined(DEBUG)
1378
1379void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
1380{
1381 // XML output:
1382 wxString s = GetClass();
1383
1384 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
1385 << TO_UTF8( m_fields[ SHEETNAME ].GetText() ) << '"' << ">\n";
1386
1387 // show all the pins, and check the linked list integrity
1388 for( SCH_SHEET_PIN* sheetPin : m_pins )
1389 sheetPin->Show( nestLevel + 1, os );
1390
1391 NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
1392}
1393
1394#endif
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
const Vec GetCenter() const
Definition: box2.h:195
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
coord_type GetTop() const
Definition: box2.h:194
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
coord_type GetRight() const
Definition: box2.h:189
coord_type GetLeft() const
Definition: box2.h:193
coord_type GetBottom() const
Definition: box2.h:190
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:255
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
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:85
const KIID m_Uuid
Definition: eda_item.h:475
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
Definition: eda_text.cpp:1008
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:103
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Store schematic specific render settings.
Definition: sch_painter.h:71
wxString AsString() const
Definition: kiid.cpp:359
Definition: kiid.h:48
Base plotter engine class.
Definition: plotter.h:110
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:141
bool GetColorMode() const
Definition: plotter.h:138
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:466
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
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:133
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:205
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
void GetContextualTextVars(wxArrayString *aVars) const
Definition: schematic.cpp:128
SCH_SHEET & Root() const
Definition: schematic.h:102
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:87
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:147
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:71
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:157
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:499
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:442
SCH_LAYER_ID m_layer
Definition: sch_item.h:497
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
const wxString & GetFileName() const
Definition: sch_screen.h:144
void DecRefCount()
Definition: sch_screen.cpp:123
void IncRefCount()
Definition: sch_screen.cpp:117
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:155
int GetRefCount() const
Definition: sch_screen.h:161
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
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.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
bool IsFullPath() 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:974
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:201
friend SCH_SHEET_PATH
Definition: sch_sheet.h:426
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:828
friend class SCH_SHEET_PIN
Definition: sch_sheet.h:497
VECTOR2I m_size
Definition: sch_sheet.h:509
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:316
bool IsRootSheet() const
Definition: sch_sheet.cpp:193
bool getInstance(SCH_SHEET_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
Definition: sch_sheet.cpp:1250
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_sheet.cpp:1063
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList, 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:986
void setPageNumber(const SCH_SHEET_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1323
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated=true)
Definition: sch_sheet.cpp:54
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
Definition: sch_sheet.cpp:368
bool HasRootInstance() const
Check to see if this sheet has a root sheet instance.
Definition: sch_sheet.cpp:1274
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:1046
int GetPenWidth() const override
Definition: sch_sheet.cpp:593
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:155
SCH_SHEET_PATH findSelf() const
Get the sheetpath of this sheet.
Definition: sch_sheet.cpp:954
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_sheet.cpp:935
VECTOR2I m_pos
Definition: sch_sheet.h:508
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:93
KIGFX::COLOR4D m_borderColor
Definition: sch_sheet.h:511
wxString GetName() const
Definition: sch_sheet.h:107
void renumberPins()
Renumber the sheet pins in the sheet.
Definition: sch_sheet.cpp:942
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:693
SCH_SHEET_PIN * GetPin(const VECTOR2I &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:581
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_sheet.cpp:1207
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:555
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:379
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:722
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_sheet.cpp:1056
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:758
std::vector< SCH_SHEET_INSTANCE > m_instances
Definition: sch_sheet.h:514
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:441
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_sheet.cpp:910
int SymbolCount() const
Count our own symbols, without the power symbols.
Definition: sch_sheet.cpp:700
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:487
SCH_SCREEN * m_screen
Definition: sch_sheet.h:501
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_sheet.cpp:648
std::vector< SCH_FIELD > m_fields
Definition: sch_sheet.h:506
KIGFX::COLOR4D m_backgroundColor
Definition: sch_sheet.h:512
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
Definition: sch_sheet.cpp:782
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:661
bool HasPin(const wxString &aName) const
Checks if the sheet already has a sheet pin named aName.
Definition: sch_sheet.cpp:396
static int ComparePageNum(const wxString &aPageNumberA, const wxString &aPageNumberB)
Compares page numbers of schematic sheets.
Definition: sch_sheet.cpp:1341
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:76
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_sheet.cpp:890
void Plot(PLOTTER *aPlotter, bool aBackground) const override
Plot the schematic item to aPlotter.
Definition: sch_sheet.cpp:1092
wxString getPageNumber(const SCH_SHEET_PATH &aInstance) const
Return the sheet page number for aInstance.
Definition: sch_sheet.cpp:1302
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_sheet.cpp:346
int GetScreenCount() const
Return the number of times the associated screen for the sheet is being used.
Definition: sch_sheet.cpp:184
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:161
SCH_SHEET & operator=(const SCH_ITEM &aSheet)
Definition: sch_sheet.cpp:1177
const SCH_SHEET_INSTANCE & GetRootInstance() const
Return the root sheet instance data.
Definition: sch_sheet.cpp:1286
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
Definition: sch_sheet.cpp:408
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:605
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:682
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_sheet.cpp:998
KIGFX::COLOR4D GetBorderColor() const
Definition: sch_sheet.h:118
std::vector< SCH_SHEET_PIN * > m_pins
Definition: sch_sheet.h:505
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:1009
bool addInstance(const SCH_SHEET_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1224
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_sheet.cpp:870
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_sheet.cpp:312
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:521
int m_borderWidth
Definition: sch_sheet.h:510
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:918
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_sheet.cpp:816
int GetBorderWidth() const
Definition: sch_sheet.h:115
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:796
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:236
bool IsVerticalOrientation() const
Definition: sch_sheet.cpp:420
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset) override
Print a schematic item.
Definition: sch_sheet.cpp:1145
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:1069
KIGFX::COLOR4D GetBackgroundColor() const
Definition: sch_sheet.h:121
Schematic symbol object.
Definition: sch_symbol.h:81
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:891
bool TextVarResolver(wxString *aToken, const PROJECT *aProject) const
Definition: title_block.cpp:96
static void GetContextualTextVars(wxArrayString *aVars)
Definition: title_block.cpp:74
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:425
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:426
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
void GRRect(wxDC *DC, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:396
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_SHEETNAME
Definition: layer_ids.h:367
@ LAYER_SHEET_BACKGROUND
Definition: layer_ids.h:377
@ LAYER_HIERLABEL
Definition: layer_ids.h:353
@ LAYER_SHEETFIELDS
Definition: layer_ids.h:369
@ LAYER_SHEET
Definition: layer_ids.h:366
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:385
@ LAYER_SHEETFILENAME
Definition: layer_ids.h:368
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
Message panel definition file.
wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:215
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:197
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
see class PGM_BASE
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
FIELDS_AUTOPLACED
Definition: sch_item.h:55
@ FIELDS_AUTOPLACED_AUTO
Definition: sch_item.h:57
#define USER_FIELD_CANONICAL
Definition: sch_sheet.cpp:51
#define SHEET_NAME_CANONICAL
Definition: sch_sheet.cpp:49
int bumpToNextGrid(const int aVal, const int aDirection)
Definition: sch_sheet.cpp:465
#define SHEET_FILE_CANONICAL
Definition: sch_sheet.cpp:50
@ 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.
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
A simple container for sheet instance information.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ 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)
Definition: trigo.cpp:183
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_SYMBOL_T
Definition: typeinfo.h:146
@ SCH_FIELD_T
Definition: typeinfo.h:145
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:173
@ SCH_SHEET_T
Definition: typeinfo.h:148
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:143
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:147
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588