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