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