KiCad PCB EDA Suite
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-2021 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 <bitmaps.h>
26 #include <core/mirror.h>
27 #include <sch_draw_panel.h>
28 #include <trigo.h>
29 #include <sch_edit_frame.h>
30 #include <plotters/plotter.h>
31 #include <string_utils.h>
32 #include <widgets/msgpanel.h>
33 #include <math/util.h> // for KiROUND
34 #include <sch_sheet.h>
35 #include <sch_sheet_path.h>
36 #include <sch_sheet_pin.h>
37 #include <sch_symbol.h>
38 #include <sch_painter.h>
39 #include <schematic.h>
41 #include <trace_helpers.h>
42 #include <pgm_base.h>
43 #include <wx/log.h>
44 
45 
46 const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx )
47 {
48  static void* locale = nullptr;
49  static wxString sheetnameDefault;
50  static wxString sheetfilenameDefault;
51  static wxString userFieldDefault;
52 
53  // Fetching translations can take a surprising amount of time when loading libraries,
54  // so only do it when necessary.
55  if( Pgm().GetLocale() != locale )
56  {
57  sheetnameDefault = _( "Sheet name" );
58  sheetfilenameDefault = _( "Sheet file" );
59  userFieldDefault = _( "Field%d" );
60  locale = Pgm().GetLocale();
61  }
62 
63  // Fixed values for the mandatory fields
64  switch( aFieldNdx )
65  {
66  case SHEETNAME: return sheetnameDefault;
67  case SHEETFILENAME: return sheetfilenameDefault;
68  default: return wxString::Format( userFieldDefault, aFieldNdx );
69  }
70 }
71 
72 
73 SCH_SHEET::SCH_SHEET( EDA_ITEM* aParent, const wxPoint& pos ) :
74  SCH_ITEM( aParent, SCH_SHEET_T )
75 {
77  m_pos = pos;
78  m_size = wxSize( Mils2iu( MIN_SHEET_WIDTH ), Mils2iu( MIN_SHEET_HEIGHT ) );
79  m_screen = nullptr;
80 
81  for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
82  {
83  m_fields.emplace_back( pos, i, this, GetDefaultFieldName( i ) );
84  m_fields.back().SetVisible( true );
85 
86  if( i == SHEETNAME )
87  m_fields.back().SetLayer( LAYER_SHEETNAME );
88  else if( i == SHEETFILENAME )
89  m_fields.back().SetLayer( LAYER_SHEETFILENAME );
90  else
91  m_fields.back().SetLayer( LAYER_SHEETFIELDS );
92  }
93 
95 
96  m_borderWidth = 0;
97  m_borderColor = COLOR4D::UNSPECIFIED;
98  m_backgroundColor = COLOR4D::UNSPECIFIED;
99 }
100 
101 
102 SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
103  SCH_ITEM( aSheet )
104 {
105  m_pos = aSheet.m_pos;
106  m_size = aSheet.m_size;
107  m_layer = aSheet.m_layer;
108  const_cast<KIID&>( m_Uuid ) = aSheet.m_Uuid;
109  m_fields = aSheet.m_fields;
111  m_screen = aSheet.m_screen;
112 
113  for( SCH_SHEET_PIN* pin : aSheet.m_pins )
114  {
115  m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
116  m_pins.back()->SetParent( this );
117  }
118 
119  for( SCH_FIELD& field : m_fields )
120  field.SetParent( this );
121 
122  m_borderWidth = aSheet.m_borderWidth;
123  m_borderColor = aSheet.m_borderColor;
125  m_instances = aSheet.m_instances;
126 
127  if( m_screen )
129 }
130 
131 
133 {
134  // also, look at the associated sheet & its reference count
135  // perhaps it should be deleted also.
136  if( m_screen )
137  {
139 
140  if( m_screen->GetRefCount() == 0 )
141  delete m_screen;
142  }
143 
144  // We own our pins; delete them
145  for( SCH_SHEET_PIN* pin : m_pins )
146  delete pin;
147 }
148 
149 
151 {
152  return new SCH_SHEET( *this );
153 }
154 
155 
157 {
158  if( aScreen == m_screen )
159  return;
160 
161  if( m_screen != nullptr )
162  {
164 
165  if( m_screen->GetRefCount() == 0 )
166  {
167  delete m_screen;
168  m_screen = nullptr;
169  }
170  }
171 
172  m_screen = aScreen;
173 
174  if( m_screen )
176 }
177 
178 
180 {
181  if( m_screen == nullptr )
182  return 0;
183 
184  return m_screen->GetRefCount();
185 }
186 
187 
189 {
190  wxCHECK_MSG( Schematic(), false, "Can't call IsRootSheet without setting a schematic" );
191 
192  return &Schematic()->Root() == this;
193 }
194 
195 
196 void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
197 {
198  for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
199  aVars->push_back( m_fields[i].GetCanonicalName().Upper() );
200 
201  for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
202  aVars->push_back( m_fields[i].GetName() );
203 
204  aVars->push_back( wxT( "#" ) );
205  aVars->push_back( wxT( "##" ) );
207 }
208 
209 
210 bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
211 {
212  for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
213  {
214  if( token->IsSameAs( m_fields[i].GetCanonicalName().Upper() ) )
215  {
216  *token = m_fields[i].GetShownText( aDepth + 1 );
217  return true;
218  }
219  }
220 
221  for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields.size(); ++i )
222  {
223  if( token->IsSameAs( m_fields[i].GetName() ) )
224  {
225  *token = m_fields[i].GetShownText( aDepth + 1 );
226  return true;
227  }
228  }
229 
230  PROJECT *project = &Schematic()->Prj();
231 
232  if( m_screen->GetTitleBlock().TextVarResolver( token, project ) )
233  {
234  return true;
235  }
236 
237  if( token->IsSameAs( wxT( "#" ) ) )
238  {
239  for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() )
240  {
241  if( sheet.Last() == this ) // Current sheet path found
242  {
243  *token = wxString::Format( "%s", sheet.GetPageNumber() );
244  return true;
245  }
246  }
247  }
248  else if( token->IsSameAs( wxT( "##" ) ) )
249  {
250  SCH_SHEET_LIST sheetList = Schematic()->GetSheets();
251  *token = wxString::Format( wxT( "%d" ), (int) sheetList.size() );
252  return true;
253  }
254 
255  return false;
256 }
257 
258 
260 {
261  return m_borderWidth == 0 && m_borderColor == COLOR4D::UNSPECIFIED;
262 }
263 
264 
266 {
267  wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
268  wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
269  aItem->GetClass() ) );
270 
271  SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
272 
273  std::swap( m_pos, sheet->m_pos );
274  std::swap( m_size, sheet->m_size );
275  m_fields.swap( sheet->m_fields );
276  std::swap( m_fieldsAutoplaced, sheet->m_fieldsAutoplaced );
277  m_pins.swap( sheet->m_pins );
278 
279  // Update parent pointers after swapping.
280  for( SCH_SHEET_PIN* sheetPin : m_pins )
281  sheetPin->SetParent( this );
282 
283  for( SCH_SHEET_PIN* sheetPin : sheet->m_pins )
284  sheetPin->SetParent( sheet );
285 
286  for( SCH_FIELD& field : m_fields )
287  field.SetParent( this );
288 
289  for( SCH_FIELD& field : sheet->m_fields )
290  field.SetParent( sheet );
291 
292  std::swap( m_borderWidth, sheet->m_borderWidth );
293  std::swap( m_borderColor, sheet->m_borderColor );
294  std::swap( m_backgroundColor, sheet->m_backgroundColor );
295  std::swap( m_instances, sheet->m_instances );
296 }
297 
298 
300 {
301  wxASSERT( aSheetPin != nullptr );
302  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
303 
304  aSheetPin->SetParent( this );
305  m_pins.push_back( aSheetPin );
306  renumberPins();
307 }
308 
309 
310 void SCH_SHEET::RemovePin( const SCH_SHEET_PIN* aSheetPin )
311 {
312  wxASSERT( aSheetPin != nullptr );
313  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
314 
315  for( auto i = m_pins.begin(); i < m_pins.end(); ++i )
316  {
317  if( *i == aSheetPin )
318  {
319  m_pins.erase( i );
320  renumberPins();
321  return;
322  }
323  }
324 }
325 
326 
327 bool SCH_SHEET::HasPin( const wxString& aName ) const
328 {
329  for( SCH_SHEET_PIN* pin : m_pins )
330  {
331  if( pin->GetText().CmpNoCase( aName ) == 0 )
332  return true;
333  }
334 
335  return false;
336 }
337 
338 
339 bool SCH_SHEET::doIsConnected( const wxPoint& aPosition ) const
340 {
341  for( SCH_SHEET_PIN* sheetPin : m_pins )
342  {
343  if( sheetPin->GetPosition() == aPosition )
344  return true;
345  }
346 
347  return false;
348 }
349 
350 
352 {
353  int leftRight = 0;
354  int topBottom = 0;
355 
356  for( SCH_SHEET_PIN* pin : m_pins )
357  {
358  switch( pin->GetEdge() )
359  {
360  case SHEET_SIDE::LEFT: leftRight++; break;
361  case SHEET_SIDE::RIGHT: leftRight++; break;
362  case SHEET_SIDE::TOP: topBottom++; break;
363  case SHEET_SIDE::BOTTOM: topBottom++; break;
364  default: break;
365  }
366  }
367 
368  return topBottom > 0 && leftRight == 0;
369 }
370 
371 
373 {
374  for( SCH_SHEET_PIN* pin : m_pins )
375  {
376  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
377  const SCH_HIERLABEL* HLabel = nullptr;
378 
379  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
380  {
381  if( !pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
382  {
383  HLabel = static_cast<SCH_HIERLABEL*>( aItem );
384  break;
385  }
386  }
387 
388  if( HLabel == nullptr ) // Corresponding hierarchical label not found.
389  return true;
390  }
391 
392  return false;
393 }
394 
395 
396 int bumpToNextGrid( const int aVal, const int aDirection )
397 {
398  constexpr int gridSize = Mils2iu( 50 );
399 
400  return ( KiROUND( aVal / gridSize ) * gridSize ) + ( aDirection * gridSize );
401 }
402 
403 
404 int SCH_SHEET::GetMinWidth( bool aFromLeft ) const
405 {
406  int pinsLeft = m_pos.x + m_size.x;
407  int pinsRight = m_pos.x;
408 
409  for( size_t i = 0; i < m_pins.size(); i++ )
410  {
411  SHEET_SIDE edge = m_pins[i]->GetEdge();
412 
413  if( edge == SHEET_SIDE::TOP || edge == SHEET_SIDE::BOTTOM )
414  {
415  EDA_RECT pinRect = m_pins[i]->GetBoundingBox();
416 
417  pinsLeft = std::min( pinsLeft, pinRect.GetLeft() );
418  pinsRight = std::max( pinsRight, pinRect.GetRight() );
419  }
420  }
421 
422  pinsLeft = bumpToNextGrid( pinsLeft, -1 );
423  pinsRight = bumpToNextGrid( pinsRight, 1 );
424 
425  int pinMinWidth;
426 
427  if( pinsLeft >= pinsRight )
428  pinMinWidth = 0;
429  else if( aFromLeft )
430  pinMinWidth = pinsRight - m_pos.x;
431  else
432  pinMinWidth = m_pos.x + m_size.x - pinsLeft;
433 
434  return std::max( pinMinWidth, Mils2iu( MIN_SHEET_WIDTH ) );
435 }
436 
437 
438 int SCH_SHEET::GetMinHeight( bool aFromTop ) const
439 {
440  int pinsTop = m_pos.y + m_size.y;
441  int pinsBottom = m_pos.y;
442 
443  for( size_t i = 0; i < m_pins.size(); i++ )
444  {
445  SHEET_SIDE edge = m_pins[i]->GetEdge();
446 
447  if( edge == SHEET_SIDE::RIGHT || edge == SHEET_SIDE::LEFT )
448  {
449  EDA_RECT pinRect = m_pins[i]->GetBoundingBox();
450 
451  pinsTop = std::min( pinsTop, pinRect.GetTop() );
452  pinsBottom = std::max( pinsBottom, pinRect.GetBottom() );
453  }
454  }
455 
456  pinsTop = bumpToNextGrid( pinsTop, -1 );
457  pinsBottom = bumpToNextGrid( pinsBottom, 1 );
458 
459  int pinMinHeight;
460 
461  if( pinsTop >= pinsBottom )
462  pinMinHeight = 0;
463  else if( aFromTop )
464  pinMinHeight = pinsBottom - m_pos.y;
465  else
466  pinMinHeight = m_pos.y + m_size.y - pinsTop;
467 
468  return std::max( pinMinHeight, Mils2iu( MIN_SHEET_HEIGHT ) );
469 }
470 
471 
473 {
474  std::vector<SCH_SHEET_PIN*> pins = m_pins;
475 
476  m_pins.clear();
477 
478  for( SCH_SHEET_PIN* pin : pins )
479  {
480  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
481  const SCH_HIERLABEL* HLabel = nullptr;
482 
483  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
484  {
485  if( pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) == 0 )
486  {
487  HLabel = static_cast<SCH_HIERLABEL*>( aItem );
488  break;
489  }
490  }
491 
492  if( HLabel )
493  m_pins.push_back( pin );
494  }
495 }
496 
497 
498 SCH_SHEET_PIN* SCH_SHEET::GetPin( const wxPoint& aPosition )
499 {
500  for( SCH_SHEET_PIN* pin : m_pins )
501  {
502  if( pin->HitTest( aPosition ) )
503  return pin;
504  }
505 
506  return nullptr;
507 }
508 
509 
511 {
512  if( GetBorderWidth() > 0 )
513  return GetBorderWidth();
514 
515  if( Schematic() )
517 
518  return Mils2iu( DEFAULT_LINE_WIDTH_MILS );
519 }
520 
521 
522 void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
523 {
524  wxSize textSize = m_fields[ SHEETNAME ].GetTextSize();
525  int borderMargin = KiROUND( GetPenWidth() / 2.0 ) + 4;
526  int margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.5 );
527 
528  if( IsVerticalOrientation() )
529  {
530  m_fields[ SHEETNAME ].SetTextPos( m_pos + wxPoint( -margin, m_size.y ) );
531  m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
532  m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM );
533  m_fields[ SHEETNAME ].SetTextAngle( TEXT_ANGLE_VERT );
534  }
535  else
536  {
537  m_fields[ SHEETNAME ].SetTextPos( m_pos + wxPoint( 0, -margin ) );
538  m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
539  m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM );
540  m_fields[ SHEETNAME ].SetTextAngle( TEXT_ANGLE_HORIZ );
541  }
542 
543  textSize = m_fields[ SHEETFILENAME ].GetTextSize();
544  margin = borderMargin + KiROUND( std::max( textSize.x, textSize.y ) * 0.4 );
545 
546  if( IsVerticalOrientation() )
547  {
548  m_fields[ SHEETFILENAME ].SetTextPos( m_pos + wxPoint( m_size.x + margin, m_size.y ) );
549  m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
550  m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP );
551  m_fields[ SHEETFILENAME ].SetTextAngle( TEXT_ANGLE_VERT );
552  }
553  else
554  {
555  m_fields[ SHEETFILENAME ].SetTextPos( m_pos + wxPoint( 0, m_size.y + margin ) );
556  m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
557  m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP );
558  m_fields[ SHEETFILENAME ].SetTextAngle( TEXT_ANGLE_HORIZ );
559  }
560 
562 }
563 
564 
565 void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const
566 {
567  aCount = 4;
568  aLayers[0] = LAYER_HIERLABEL;
569  aLayers[1] = LAYER_SHEET;
570  aLayers[2] = LAYER_SHEET_BACKGROUND;
571  aLayers[3] = LAYER_SELECTION_SHADOWS;
572 }
573 
574 
576 {
577  wxPoint end;
578  EDA_RECT box( m_pos, m_size );
579  int lineWidth = GetPenWidth();
580  int textLength = 0;
581 
582  // Calculate bounding box X size:
583  end.x = std::max( m_size.x, textLength );
584 
585  // Calculate bounding box pos:
586  end.y = m_size.y;
587  end += m_pos;
588 
589  box.SetEnd( end );
590  box.Inflate( lineWidth / 2 );
591 
592  return box;
593 }
594 
595 
597 {
599 
600  for( const SCH_FIELD& field : m_fields )
601  box.Merge( field.GetBoundingBox() );
602 
603  return box;
604 }
605 
606 
608 {
609  EDA_RECT box( m_pos, m_size );
610  return box.GetCenter();
611 }
612 
613 
615 {
616  int n = 0;
617 
618  if( m_screen )
619  {
620  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SYMBOL_T ) )
621  {
622  SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
623 
624  if( symbol->GetField( VALUE_FIELD )->GetText().GetChar( 0 ) != '#' )
625  n++;
626  }
627 
628  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
629  n += static_cast<const SCH_SHEET*>( aItem )->SymbolCount();
630  }
631 
632  return n;
633 }
634 
635 
636 bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
637 {
638  if( m_screen )
639  {
640  // Only check the root sheet once and don't recurse.
641  if( !GetParent() )
642  {
643  if( m_screen && m_screen->GetFileName().Cmp( aFilename ) == 0 )
644  {
645  *aScreen = m_screen;
646  return true;
647  }
648  }
649 
650  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
651  {
652  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
653  SCH_SCREEN* screen = sheet->m_screen;
654 
655  // Must use the screen's path (which is always absolute) rather than the
656  // sheet's (which could be relative).
657  if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
658  {
659  *aScreen = screen;
660  return true;
661  }
662 
663  if( sheet->SearchHierarchy( aFilename, aScreen ) )
664  return true;
665  }
666  }
667 
668  return false;
669 }
670 
671 
673 {
674  if( m_screen )
675  {
676  aList->push_back( this );
677 
678  if( m_screen == aScreen )
679  return true;
680 
681  for( auto item : m_screen->Items().OfType( SCH_SHEET_T ) )
682  {
683  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
684 
685  if( sheet->LocatePathOfScreen( aScreen, aList ) )
686  {
687  return true;
688  }
689  }
690 
691  aList->pop_back();
692  }
693 
694  return false;
695 }
696 
697 
699 {
700  int count = 1; //1 = this!!
701 
702  if( m_screen )
703  {
704  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
705  count += static_cast<SCH_SHEET*>( aItem )->CountSheets();
706  }
707 
708  return count;
709 }
710 
711 
712 void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
713 {
714  aList.emplace_back( _( "Sheet Name" ), m_fields[ SHEETNAME ].GetText() );
715 
716  if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
717  {
718  SCH_SHEET_PATH path = schframe->GetCurrentSheet();
719  path.push_back( this );
720 
721  aList.emplace_back( _( "Hierarchical Path" ), path.PathHumanReadable( false ) );
722  }
723 
724  aList.emplace_back( _( "File Name" ), m_fields[ SHEETFILENAME ].GetText() );
725 }
726 
727 
728 void SCH_SHEET::Move( const wxPoint& aMoveVector )
729 {
730  m_pos += aMoveVector;
731 
732  for( SCH_SHEET_PIN* pin : m_pins )
733  pin->Move( aMoveVector );
734 
735  for( SCH_FIELD& field : m_fields )
736  field.Move( aMoveVector );
737 }
738 
739 
740 void SCH_SHEET::Rotate( const wxPoint& aCenter )
741 {
742  wxPoint prev = m_pos;
743 
744  RotatePoint( &m_pos, aCenter, 900 );
745  RotatePoint( &m_size.x, &m_size.y, 900 );
746 
747  if( m_size.x < 0 )
748  {
749  m_pos.x += m_size.x;
750  m_size.x = -m_size.x;
751  }
752 
753  if( m_size.y < 0 )
754  {
755  m_pos.y += m_size.y;
756  m_size.y = -m_size.y;
757  }
758 
759  // Pins must be rotated first as that's how we determine vertical vs horizontal
760  // orientation for auto-placement
761  for( SCH_SHEET_PIN* sheetPin : m_pins )
762  sheetPin->Rotate( aCenter );
763 
765  {
766  AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
767  }
768  else
769  {
770  // Move the fields to the new position because the parent itself has moved.
771  for( SCH_FIELD& field : m_fields )
772  {
773  wxPoint pos = field.GetTextPos();
774  pos.x -= prev.x - m_pos.x;
775  pos.y -= prev.y - m_pos.y;
776  field.SetTextPos( pos );
777  }
778  }
779 }
780 
781 
782 void SCH_SHEET::MirrorVertically( int aCenter )
783 {
784  MIRROR( m_pos.y, aCenter );
785  m_pos.y -= m_size.y;
786 
787  for( SCH_SHEET_PIN* sheetPin : m_pins )
788  sheetPin->MirrorVertically( aCenter );
789 }
790 
791 
792 void SCH_SHEET::MirrorHorizontally( int aCenter )
793 {
794  MIRROR( m_pos.x, aCenter );
795  m_pos.x -= m_size.x;
796 
797  for( SCH_SHEET_PIN* sheetPin : m_pins )
798  sheetPin->MirrorHorizontally( aCenter );
799 }
800 
801 
802 void SCH_SHEET::SetPosition( const wxPoint& aPosition )
803 {
804  // Remember the sheet and all pin sheet positions must be
805  // modified. So use Move function to do that.
806  Move( aPosition - m_pos );
807 }
808 
809 
810 void SCH_SHEET::Resize( const wxSize& aSize )
811 {
812  if( aSize == m_size )
813  return;
814 
815  m_size = aSize;
816 
817  // Move the fields if we're in autoplace mode
819  AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
820 
821  // Move the sheet labels according to the new sheet size.
822  for( SCH_SHEET_PIN* sheetPin : m_pins )
823  sheetPin->ConstrainOnEdge( sheetPin->GetPosition() );
824 }
825 
826 
827 bool SCH_SHEET::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
828 {
829  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
830 
831  // Sheets are searchable via the child field and pin item text.
832  return false;
833 }
834 
835 
837 {
838  int id = 2;
839 
840  for( SCH_SHEET_PIN* pin : m_pins )
841  {
842  pin->SetNumber( id );
843  id++;
844  }
845 }
846 
847 
848 void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
849 {
850  for( SCH_SHEET_PIN* sheetPin : m_pins )
851  {
852  wxCHECK2_MSG( sheetPin->Type() == SCH_SHEET_PIN_T, continue,
853  wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
854 
855  sheetPin->GetEndPoints( aItemList );
856  }
857 }
858 
859 
860 bool SCH_SHEET::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
861  const SCH_SHEET_PATH* aPath )
862 {
863  bool changed = false;
864 
865  for( SCH_SHEET_PIN* sheetPin : m_pins )
866  changed |= sheetPin->UpdateDanglingState( aItemList );
867 
868  return changed;
869 }
870 
871 
872 std::vector<wxPoint> SCH_SHEET::GetConnectionPoints() const
873 {
874  std::vector<wxPoint> retval;
875 
876  for( SCH_SHEET_PIN* sheetPin : m_pins )
877  retval.push_back( sheetPin->GetPosition() );
878 
879  return retval;
880 }
881 
882 
883 SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICAD_T aFilterTypes[] )
884 {
885  KICAD_T stype;
886 
887  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
888  {
889  // If caller wants to inspect my type
890  if( stype == SCH_LOCATE_ANY_T || stype == Type() )
891  {
892  if( SEARCH_RESULT::QUIT == aInspector( this, nullptr ) )
893  return SEARCH_RESULT::QUIT;
894  }
895 
896  if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
897  {
898  // Test the sheet fields.
899  for( SCH_FIELD& field : m_fields )
900  {
901  if( SEARCH_RESULT::QUIT == aInspector( &field, this ) )
902  return SEARCH_RESULT::QUIT;
903  }
904  }
905 
906  if( stype == SCH_LOCATE_ANY_T || stype == SCH_SHEET_PIN_T )
907  {
908  // Test the sheet labels.
909  for( SCH_SHEET_PIN* sheetPin : m_pins )
910  {
911  if( SEARCH_RESULT::QUIT == aInspector( sheetPin, this ) )
912  return SEARCH_RESULT::QUIT;
913  }
914  }
915  }
916 
918 }
919 
920 
921 void SCH_SHEET::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
922 {
923  for( SCH_FIELD& field : m_fields )
924  aFunction( &field );
925 
926  for( SCH_SHEET_PIN* pin : m_pins )
927  aFunction( pin );
928 }
929 
930 
931 wxString SCH_SHEET::GetSelectMenuText( EDA_UNITS aUnits ) const
932 {
933  return wxString::Format( _( "Hierarchical Sheet %s" ),
934  m_fields[ SHEETNAME ].GetText() );
935 }
936 
937 
939 {
941 }
942 
943 
944 bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
945 {
946  EDA_RECT rect = GetBodyBoundingBox();
947 
948  rect.Inflate( aAccuracy );
949 
950  return rect.Contains( aPosition );
951 }
952 
953 
954 bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
955 {
956  EDA_RECT rect = aRect;
957 
958  rect.Inflate( aAccuracy );
959 
960  if( aContained )
961  return rect.Contains( GetBodyBoundingBox() );
962 
963  return rect.Intersects( GetBodyBoundingBox() );
964 }
965 
966 
967 void SCH_SHEET::Plot( PLOTTER* aPlotter ) const
968 {
969  wxString msg;
970  wxPoint pos;
971  auto* settings = dynamic_cast<KIGFX::SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
972  bool override = settings ? settings->m_OverrideItemColors : false;
973  COLOR4D borderColor = GetBorderColor();
974  COLOR4D backgroundColor = GetBackgroundColor();
975 
976  if( override || borderColor == COLOR4D::UNSPECIFIED )
977  borderColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET );
978 
979  if( override || backgroundColor == COLOR4D::UNSPECIFIED )
980  backgroundColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_SHEET_BACKGROUND );
981 
982  // Do not fill shape in B&W mode, otherwise texts are unreadable
983  bool fill = aPlotter->GetColorMode();
984 
985  if( fill )
986  {
987  aPlotter->SetColor( backgroundColor );
988  aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::FILLED_SHAPE, 1 );
989  }
990 
991  aPlotter->SetColor( borderColor );
992 
993  int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() );
994  aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::NO_FILL, penWidth );
995 
996  // Plot sheet pins
997  for( SCH_SHEET_PIN* sheetPin : m_pins )
998  sheetPin->Plot( aPlotter );
999 
1000  // Plot the fields
1001  for( const SCH_FIELD& field : m_fields )
1002  field.Plot( aPlotter );
1003 }
1004 
1005 
1006 void SCH_SHEET::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
1007 {
1008  wxDC* DC = aSettings->GetPrintDC();
1009  wxPoint pos = m_pos + aOffset;
1010  int lineWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
1011  const auto* settings = dynamic_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
1012  bool override = settings && settings->m_OverrideItemColors;
1013  COLOR4D border = GetBorderColor();
1014  COLOR4D background = GetBackgroundColor();
1015 
1016  if( override || border == COLOR4D::UNSPECIFIED )
1017  border = aSettings->GetLayerColor( LAYER_SHEET );
1018 
1019  if( override || background == COLOR4D::UNSPECIFIED )
1020  background = aSettings->GetLayerColor( LAYER_SHEET_BACKGROUND );
1021 
1022  if( GetGRForceBlackPenState() ) // printing in black & white
1023  background = COLOR4D::UNSPECIFIED;
1024 
1025  if( background != COLOR4D::UNSPECIFIED )
1026  {
1027  GRFilledRect( nullptr, DC, pos.x, pos.y, pos.x + m_size.x, pos.y + m_size.y, 0,
1028  background, background );
1029  }
1030 
1031  GRRect( nullptr, DC, pos.x, pos.y, pos.x + m_size.x, pos.y + m_size.y, lineWidth, border );
1032 
1033  for( SCH_FIELD& field : m_fields )
1034  field.Print( aSettings, aOffset );
1035 
1036  for( SCH_SHEET_PIN* sheetPin : m_pins )
1037  sheetPin->Print( aSettings, aOffset );
1038 }
1039 
1040 
1042 {
1043  wxCHECK_MSG( Type() == aItem.Type(), *this,
1044  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1045  GetClass() );
1046 
1047  if( &aItem != this )
1048  {
1049  SCH_ITEM::operator=( aItem );
1050 
1051  SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
1052 
1053  m_pos = sheet->m_pos;
1054  m_size = sheet->m_size;
1055  m_fields = sheet->m_fields;
1056 
1057  for( SCH_SHEET_PIN* pin : sheet->m_pins )
1058  {
1059  m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
1060  m_pins.back()->SetParent( this );
1061  }
1062 
1063  for( const SCH_SHEET_INSTANCE& instance : sheet->m_instances )
1064  m_instances.emplace_back( instance );
1065  }
1066 
1067  return *this;
1068 }
1069 
1070 
1071 bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const
1072 {
1073  if( Type() != aItem.Type() )
1074  return Type() < aItem.Type();
1075 
1076  auto sheet = static_cast<const SCH_SHEET*>( &aItem );
1077 
1078  if (m_fields[ SHEETNAME ].GetText() != sheet->m_fields[ SHEETNAME ].GetText() )
1079  return m_fields[ SHEETNAME ].GetText() < sheet->m_fields[ SHEETNAME ].GetText();
1080 
1081  if (m_fields[ SHEETFILENAME ].GetText() != sheet->m_fields[ SHEETFILENAME ].GetText() )
1082  return m_fields[ SHEETFILENAME ].GetText() < sheet->m_fields[ SHEETFILENAME ].GetText();
1083 
1084  return false;
1085 }
1086 
1087 
1088 bool SCH_SHEET::AddInstance( const KIID_PATH& aSheetPath )
1089 {
1090  // a empty sheet path is illegal:
1091  wxCHECK( aSheetPath.size() > 0, false );
1092 
1093  wxString path;
1094 
1095  for( const SCH_SHEET_INSTANCE& instance : m_instances )
1096  {
1097  // if aSheetPath is found, nothing to do:
1098  if( instance.m_Path == aSheetPath )
1099  return false;
1100  }
1101 
1102  SCH_SHEET_INSTANCE instance;
1103 
1104  instance.m_Path = aSheetPath;
1105 
1106  // This entry does not exist: add it with an empty page number.
1107  m_instances.emplace_back( instance );
1108  return true;
1109 }
1110 
1111 
1112 wxString SCH_SHEET::GetPageNumber( const SCH_SHEET_PATH& aInstance ) const
1113 {
1114  wxString pageNumber;
1115  KIID_PATH path = aInstance.Path();
1116 
1117  for( const SCH_SHEET_INSTANCE& instance : m_instances )
1118  {
1119  if( instance.m_Path == path )
1120  {
1121  pageNumber = instance.m_PageNumber;
1122  break;
1123  }
1124  }
1125 
1126  return pageNumber;
1127 }
1128 
1129 
1130 void SCH_SHEET::SetPageNumber( const SCH_SHEET_PATH& aInstance, const wxString& aPageNumber )
1131 {
1132  KIID_PATH path = aInstance.Path();
1133 
1134  for( SCH_SHEET_INSTANCE& instance : m_instances )
1135  {
1136  if( instance.m_Path == path )
1137  {
1138  instance.m_PageNumber = aPageNumber;
1139  break;
1140  }
1141  }
1142 }
1143 
1144 
1145 int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
1146 {
1147  if( aPageNumberA == aPageNumberB )
1148  return 0; // A == B
1149 
1150  // First sort numerically if the page numbers are integers
1151  long pageA, pageB;
1152  bool isIntegerPageA = aPageNumberA.ToLong( &pageA );
1153  bool isIntegerPageB = aPageNumberB.ToLong( &pageB );
1154 
1155  if( isIntegerPageA && isIntegerPageB )
1156  {
1157  if( pageA < pageB )
1158  return -1; //A < B
1159  else
1160  return 1; // A > B
1161  }
1162 
1163  // Numerical page numbers always before strings
1164  if( isIntegerPageA )
1165  return -1; //A < B
1166  else if( isIntegerPageB )
1167  return 1; // A > B
1168 
1169  // If not numeric, then sort as strings using natural sort
1170  int result = StrNumCmp( aPageNumberA, aPageNumberB );
1171 
1172  if( result > 0 )
1173  return 1; // A > B
1174 
1175  return -1; //A < B
1176 }
1177 
1178 
1179 #if defined(DEBUG)
1180 
1181 void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
1182 {
1183  // XML output:
1184  wxString s = GetClass();
1185 
1186  NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
1187  << TO_UTF8( m_fields[ SHEETNAME ].GetText() ) << '"' << ">\n";
1188 
1189  // show all the pins, and check the linked list integrity
1190  for( SCH_SHEET_PIN* sheetPin : m_pins )
1191  sheetPin->Show( nestLevel + 1, os );
1192 
1193  NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
1194 }
1195 
1196 #endif
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Definition: eda_text.h:71
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
const wxString & GetFileName() const
Definition: sch_screen.h:145
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:565
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:636
SCH_SHEET_PIN * GetPin(const wxPoint &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:498
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_sheet.cpp:782
void Merge(const EDA_RECT &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: eda_rect.cpp:432
Container for project specific data.
Definition: project.h:62
KIGFX::COLOR4D m_borderColor
Definition: sch_sheet.h:459
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:675
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
Definition: sch_sheet.h:47
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
void GRFilledRect(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, const COLOR4D &Color, const COLOR4D &BgColor)
Definition: gr_basic.cpp:811
int GetTop() const
Definition: eda_rect.h:113
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:404
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:848
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
friend class SCH_SHEET_PIN
Definition: sch_sheet.h:448
int GetLeft() const
Definition: eda_rect.h:112
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:167
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:156
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:97
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:196
wxSize m_size
Definition: sch_sheet.h:457
static int ComparePageNum(const wxString &aPageNumberA, const wxString &aPageNumberB)
Compares page numbers of schematic sheets.
Definition: sch_sheet.cpp:1145
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
bool doIsConnected(const wxPoint &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
Definition: sch_sheet.cpp:339
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:372
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:156
KIGFX::COLOR4D GetBorderColor() const
Definition: sch_sheet.h:111
bool UsesDefaultStroke() const
Test this sheet to see if the default stroke is used to draw the outline.
Definition: sch_sheet.cpp:259
Schematic editor (Eeschema) main window.
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:438
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, const COLOR4D &aColor)
Definition: gr_basic.cpp:774
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: sch_sheet.cpp:931
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_sheet.cpp:1071
The base class for create windows for drawing purpose.
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_sheet.cpp:792
wxPoint m_pos
Definition: sch_sheet.h:456
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
Definition: sch_sheet.cpp:299
static void GetContextualTextVars(wxArrayString *aVars)
Definition: title_block.cpp:73
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:483
void SetPageNumber(const SCH_SHEET_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1130
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:94
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
std::vector< SCH_SHEET_INSTANCE > m_instances
Definition: sch_sheet.h:462
#define MIN_SHEET_WIDTH
Definition: sch_sheet.h:37
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:740
int GetBottom() const
Definition: eda_rect.h:114
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
void pop_back()
Forwarded method from std::vector.
void Plot(PLOTTER *aPlotter) const override
Plot the schematic item to aPlotter.
Definition: sch_sheet.cpp:967
KIGFX::COLOR4D GetBackgroundColor() const
Definition: sch_sheet.h:114
int GetScreenCount() const
Return the number of times the associated screen for the sheet is being used.
Definition: sch_sheet.cpp:179
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void renumberPins()
Renumber the sheet pins in the sheet.
Definition: sch_sheet.cpp:836
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:712
wxString GetClass() const override
Return the class name.
Definition: sch_sheet.h:72
int GetBorderWidth() const
Definition: sch_sheet.h:108
SCH_LAYER_ID m_layer
Definition: sch_item.h:481
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_sheet.cpp:938
Field Value of part, i.e. "3.3K".
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:596
SCH_SHEET(EDA_ITEM *aParent=nullptr, const wxPoint &pos=wxPoint(0, 0))
Definition: sch_sheet.cpp:73
int m_borderWidth
Definition: sch_sheet.h:458
void SetEnd(int x, int y)
Definition: eda_rect.h:182
int GetPenWidth() const override
Definition: sch_sheet.cpp:510
bool IsRootSheet() const
Definition: sch_sheet.cpp:188
std::vector< SCH_SHEET_PIN * > m_pins
Definition: sch_sheet.h:453
int GetRight() const
Definition: eda_rect.h:111
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) 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:883
EDA_ITEM * GetParent() const
Definition: eda_item.h:115
#define _(s)
const EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:575
wxLogTrace helper definitions.
wxDC * GetPrintDC() const
static const wxString GetDefaultFieldName(int aFieldNdx)
Definition: sch_sheet.cpp:46
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
int SymbolCount() const
Count our own symbols, without the power symbols.
Definition: sch_sheet.cpp:614
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::vector< wxPoint > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_sheet.cpp:872
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:472
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:180
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:310
virtual void SetColor(const COLOR4D &color)=0
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset) override
Print a schematic item.
Definition: sch_sheet.cpp:1006
const KIID m_Uuid
Definition: eda_item.h:475
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
std::vector< SCH_FIELD > m_fields
Definition: sch_sheet.h:454
EDA_UNITS
Definition: eda_units.h:38
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
Definition: sch_sheet.cpp:698
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
void DecRefCount()
Definition: sch_screen.cpp:124
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:672
Base plotter engine class.
Definition: plotter.h:121
SCH_SHEET & Root() const
Definition: schematic.h:92
A simple container for sheet instance information.
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_sheet.cpp:265
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
Definition: sch_sheet.cpp:921
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:150
see class PGM_BASE
Schematic symbol object.
Definition: sch_symbol.h:78
const wxChar *const traceFindItem
Flag to enable find debug tracing.
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
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:860
bool IsVerticalOrientation() const
Definition: sch_sheet.cpp:351
void SetPosition(const wxPoint &aPosition) override
Definition: sch_sheet.cpp:802
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
KIGFX::COLOR4D m_backgroundColor
Definition: sch_sheet.h:460
Handle the component boundary box.
Definition: eda_rect.h:42
SCH_SCREEN * m_screen
Definition: sch_sheet.h:450
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:73
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:38
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:191
int GetDefaultPenWidth() const
wxPoint GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:607
bool TextVarResolver(wxString *aToken, const PROJECT *aProject) const
Definition: title_block.cpp:91
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
Definition: sch_sheet_pin.h:45
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:210
#define TEXT_ANGLE_VERT
Definition: eda_text.h:72
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:522
const wxPoint GetCenter() const
Definition: eda_rect.h:104
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:196
bool Matches(const wxFindReplaceData &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_sheet.cpp:827
bool HasPin(const wxString &aName) const
Checks if the sheet already has a sheet pin named aName.
Definition: sch_sheet.cpp:327
SEARCH_RESULT
Definition: eda_item.h:41
Message panel definition file.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
void Move(const wxPoint &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_sheet.cpp:728
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:154
int bumpToNextGrid(const int aVal, const int aDirection)
Definition: sch_sheet.cpp:396
wxString GetPageNumber(const SCH_SHEET_PATH &aInstance) const
Return the sheet page number for aInstance.
Definition: sch_sheet.cpp:1112
SCH_SHEET & operator=(const SCH_ITEM &aSheet)
Definition: sch_sheet.cpp:1041
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
void IncRefCount()
Definition: sch_screen.cpp:118
bool AddInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1088
int GetRefCount() const
Definition: sch_screen.h:162
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void Resize(const wxSize &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:810
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Test if aPosition is contained within or on the bounding box of an item.
Definition: sch_sheet.cpp:944
bool GetColorMode() const
Definition: plotter.h:153