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-2019 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 
30 #include <fctsys.h>
31 #include <sch_draw_panel.h>
32 #include <gr_text.h>
33 #include <trigo.h>
34 #include <richio.h>
35 #include <sch_edit_frame.h>
36 #include <plotter.h>
37 #include <kicad_string.h>
38 #include <msgpanel.h>
39 #include <math/util.h> // for KiROUND
40 
41 #include <sch_sheet.h>
42 #include <sch_sheet_path.h>
43 #include <sch_component.h>
44 #include <netlist_object.h>
45 #include <trace_helpers.h>
46 
47 
50 {
52  m_pos = pos;
53  m_size = wxSize( Mils2iu( MIN_SHEET_WIDTH ), Mils2iu( MIN_SHEET_HEIGHT ) );
57  m_screen = NULL;
58  m_name.Printf( wxT( "Sheet%8.8lX" ), (long) m_TimeStamp );
59  m_fileName.Printf( wxT( "file%8.8lX.sch" ), (long) m_TimeStamp );
60 }
61 
62 
63 SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
64  SCH_ITEM( aSheet )
65 {
66  m_pos = aSheet.m_pos;
67  m_size = aSheet.m_size;
68  m_Layer = aSheet.m_Layer;
69  SetTimeStamp( aSheet.m_TimeStamp );
72  m_screen = aSheet.m_screen;
73  m_name = aSheet.m_name;
74  m_fileName = aSheet.m_fileName;
75 
76  for( SCH_SHEET_PIN* pin : aSheet.m_pins )
77  {
78  m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
79  m_pins.back()->SetParent( this );
80  }
81 
82  if( m_screen )
84 }
85 
86 
88 {
89  // also, look at the associated sheet & its reference count
90  // perhaps it should be deleted also.
91  if( m_screen )
92  {
94 
95  if( m_screen->GetRefCount() == 0 )
96  delete m_screen;
97  }
98 
99  // We own our pins; delete them
100  for( SCH_SHEET_PIN* pin : m_pins )
101  delete pin;
102 }
103 
104 
106 {
107  return new SCH_SHEET( *this );
108 }
109 
110 
112 {
113  if( aScreen == m_screen )
114  return;
115 
116  if( m_screen != NULL )
117  {
119 
120  if( m_screen->GetRefCount() == 0 )
121  {
122  delete m_screen;
123  m_screen = NULL;
124  }
125  }
126 
127  m_screen = aScreen;
128 
129  if( m_screen )
131 }
132 
133 
135 {
136  if( m_screen == NULL )
137  return 0;
138 
139  return m_screen->GetRefCount();
140 }
141 
142 
144 {
145  SCH_SHEET* sheet = dynamic_cast< SCH_SHEET* >( GetParent() );
146 
147  if( sheet == NULL )
148  return this;
149 
150  // Recurse until a sheet is found with no parent which is the root sheet.
151  return sheet->GetRootSheet();
152 }
153 
154 
156 {
157  wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
158  wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
159  GetChars( aItem->GetClass() ) ) );
160 
161  SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
162 
163  std::swap( m_pos, sheet->m_pos );
164  std::swap( m_size, sheet->m_size );
165  std::swap( m_name, sheet->m_name );
166  std::swap( m_sheetNameSize, sheet->m_sheetNameSize );
167  std::swap( m_fileNameSize, sheet->m_fileNameSize );
168  m_pins.swap( sheet->m_pins );
169 
170  // Update parent pointers after swapping.
171  for( SCH_SHEET_PIN* sheetPin : m_pins )
172  sheetPin->SetParent( this );
173 
174  for( SCH_SHEET_PIN* sheetPin : sheet->m_pins )
175  sheetPin->SetParent( sheet );
176 }
177 
178 
180 {
181  wxASSERT( aSheetPin != NULL );
182  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
183 
184  m_pins.push_back( aSheetPin );
185  renumberPins();
186 }
187 
188 
190 {
191  wxASSERT( aSheetPin != NULL );
192  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
193 
194  for( auto i = m_pins.begin(); i < m_pins.end(); ++i )
195  {
196  if( *i == aSheetPin )
197  {
198  m_pins.erase( i );
199  renumberPins();
200  return;
201  }
202  }
203 
204  wxLogDebug( wxT( "Fix me: attempt to remove label %s which is not in sheet %s." ),
205  GetChars( aSheetPin->GetShownText() ), GetChars( m_name ) );
206 }
207 
208 
209 bool SCH_SHEET::HasPin( const wxString& aName )
210 {
211  for( SCH_SHEET_PIN* pin : m_pins )
212  {
213  if( pin->GetText().CmpNoCase( aName ) == 0 )
214  return true;
215  }
216 
217  return false;
218 }
219 
220 
222 {
223  int leftRight = 0;
224  int topBottom = 0;
225 
226  for( SCH_SHEET_PIN* pin : m_pins )
227  {
228  switch( pin->GetEdge() )
229  {
230  case SHEET_LEFT_SIDE: leftRight++; break;
231  case SHEET_RIGHT_SIDE: leftRight++; break;
232  case SHEET_TOP_SIDE: topBottom++; break;
233  case SHEET_BOTTOM_SIDE: topBottom++; break;
234  default: break;
235  }
236  }
237 
238  return topBottom > 0 && leftRight == 0;
239 }
240 
241 
243 {
244  for( SCH_SHEET_PIN* pin : m_pins )
245  {
246  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
247  const SCH_HIERLABEL* HLabel = nullptr;
248  for( auto aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
249  {
250  if( !pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
251  {
252  HLabel = static_cast<SCH_HIERLABEL*>( aItem );
253  break;
254  }
255  }
256 
257  if( HLabel == nullptr ) // Corresponding hierarchical label not found.
258  return true;
259  }
260 
261  return false;
262 }
263 
264 
266 {
267  int width = Mils2iu( MIN_SHEET_WIDTH );
268 
269  for( size_t i = 0; i < m_pins.size(); i++ )
270  {
271  int edge = m_pins[i]->GetEdge();
272  EDA_RECT pinRect = m_pins[i]->GetBoundingBox();
273 
274  wxASSERT( edge != SHEET_UNDEFINED_SIDE );
275 
276  if( edge == SHEET_TOP_SIDE || edge == SHEET_BOTTOM_SIDE )
277  {
278  if( width < pinRect.GetRight() - m_pos.x )
279  width = pinRect.GetRight() - m_pos.x;
280  }
281  else
282  {
283  if( width < pinRect.GetWidth() )
284  width = pinRect.GetWidth();
285 
286  for( size_t j = 0; j < m_pins.size(); j++ )
287  {
288  // Check for pin directly across from the current pin.
289  if( (i == j) || (m_pins[i]->GetPosition().y != m_pins[j]->GetPosition().y) )
290  continue;
291 
292  if( width < pinRect.GetWidth() + m_pins[j]->GetBoundingBox().GetWidth() )
293  {
294  width = pinRect.GetWidth() + m_pins[j]->GetBoundingBox().GetWidth();
295  break;
296  }
297  }
298  }
299  }
300 
301  return width;
302 }
303 
304 
306 {
307  int height = Mils2iu( MIN_SHEET_HEIGHT );
308 
309  for( size_t i = 0; i < m_pins.size(); i++ )
310  {
311  int edge = m_pins[i]->GetEdge();
312  EDA_RECT pinRect = m_pins[i]->GetBoundingBox();
313 
314  // Make sure pin is on top or bottom side of sheet.
315  if( edge == SHEET_RIGHT_SIDE || edge == SHEET_LEFT_SIDE )
316  {
317  if( height < pinRect.GetBottom() - m_pos.y )
318  height = pinRect.GetBottom() - m_pos.y;
319  }
320  else
321  {
322  if( height < pinRect.GetHeight() )
323  height = pinRect.GetHeight();
324 
325  for( size_t j = 0; j < m_pins.size(); j++ )
326  {
327  // Check for pin directly above or below the current pin.
328  if( (i == j) || (m_pins[i]->GetPosition().x != m_pins[j]->GetPosition().x) )
329  continue;
330 
331  if( height < pinRect.GetHeight() + m_pins[j]->GetBoundingBox().GetHeight() )
332  {
333  height = pinRect.GetHeight() + m_pins[j]->GetBoundingBox().GetHeight();
334  break;
335  }
336  }
337  }
338  }
339 
340  return height;
341 }
342 
343 
345 {
346  auto i = m_pins.begin();
347 
348  while( i != m_pins.end() )
349  {
350  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
351  const SCH_HIERLABEL* HLabel = NULL;
352 
353  for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
354  {
355  if( (*i)->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) == 0 )
356  {
357  HLabel = static_cast<SCH_HIERLABEL*>( aItem );
358  break;
359  }
360  }
361 
362  if( HLabel == NULL ) // Hlabel not found: delete sheet label.
363  i = m_pins.erase( i );
364  else
365  ++i;
366  }
367 }
368 
369 
371 {
372  for( SCH_SHEET_PIN* pin : m_pins )
373  {
374  if( pin->HitTest( aPosition ) )
375  return pin;
376  }
377 
378  return NULL;
379 }
380 
381 
383 {
384  return GetDefaultLineThickness();
385 }
386 
387 
389 {
390  wxPoint pos = m_pos;
391  int margin = KiROUND( GetPenSize() / 2.0 + 4 + m_sheetNameSize * 0.3 );
392 
393  if( IsVerticalOrientation() )
394  {
395  pos.x -= margin;
396  pos.y += m_size.y;
397  }
398  else
399  {
400  pos.y -= margin;
401  }
402 
403  return pos;
404 }
405 
406 
408 {
409  wxPoint pos = m_pos;
410  int margin = KiROUND( GetPenSize() / 2.0 + 4 + m_fileNameSize * 0.4 );
411 
412  if( IsVerticalOrientation() )
413  {
414  pos.x += m_size.x + margin;
415  pos.y += m_size.y;
416  }
417  else
418  {
419  pos.y += m_size.y + margin;
420  }
421 
422  return pos;
423 }
424 
425 
426 void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const
427 {
428  aCount = 4;
429  aLayers[0] = LAYER_HIERLABEL;
430  aLayers[1] = LAYER_SHEET;
431  aLayers[2] = LAYER_SHEET_BACKGROUND;
432  aLayers[3] = LAYER_SELECTION_SHADOWS;
433 }
434 
435 
436 void SCH_SHEET::Print( wxDC* aDC, const wxPoint& aOffset )
437 {
438  wxString Text;
439  int name_orientation;
440  wxPoint pos_sheetname,pos_filename;
441  wxPoint pos = m_pos + aOffset;
442  int lineWidth = GetPenSize();
443  int textWidth;
444  wxSize textSize;
446 
447  GRRect( nullptr, aDC, pos.x, pos.y, pos.x + m_size.x, pos.y + m_size.y, lineWidth, color );
448 
449  pos_sheetname = GetSheetNamePosition() + aOffset;
450  pos_filename = GetFileNamePosition() + aOffset;
451 
452  if( IsVerticalOrientation() )
453  name_orientation = TEXT_ANGLE_VERT;
454  else
455  name_orientation = TEXT_ANGLE_HORIZ;
456 
457  /* Draw text : SheetName */
458  Text = wxT( "Sheet: " ) + m_name;
459  textSize = wxSize( m_sheetNameSize, m_sheetNameSize );
460  textWidth = Clamp_Text_PenSize( lineWidth, textSize, false );
461  GRText( aDC, pos_sheetname, GetLayerColor( LAYER_SHEETNAME ), Text, name_orientation,
462  textSize, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM, textWidth, false, false );
463 
464  /* Draw text : FileName */
465  Text = wxT( "File: " ) + m_fileName;
466  textSize = wxSize( m_fileNameSize, m_fileNameSize );
467  textWidth = Clamp_Text_PenSize( lineWidth, textSize, false );
468  GRText( aDC, pos_filename, GetLayerColor( LAYER_SHEETFILENAME ), Text, name_orientation,
469  textSize, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP, textWidth, false, false );
470 
471  /* Draw text : SheetLabel */
472  for( SCH_SHEET_PIN* sheetPin : m_pins )
473  sheetPin->Print( aDC, aOffset );
474 }
475 
476 
478 {
479  wxPoint end;
480  EDA_RECT box( m_pos, m_size );
481  int lineWidth = GetPenSize();
482 
483  // Determine length of texts
484  wxString text = wxT( "Sheet: " ) + m_name;
485  int textlen = GraphicTextWidth( text, wxSize( m_sheetNameSize, m_sheetNameSize ),
486  false, false );
487 
488  text = wxT( "File: " ) + m_fileName;
489  int textlen2 = GraphicTextWidth( text, wxSize( m_fileNameSize, m_fileNameSize ),
490  false, false );
491 
492  // Calculate bounding box X size:
493  textlen = std::max( textlen, textlen2 );
494  end.x = std::max( m_size.x, textlen );
495 
496  // Calculate bounding box pos:
497  end.y = m_size.y;
498  end += m_pos;
499 
500  // Move upper and lower limits to include texts:
501  box.SetY( box.GetY() - ( KiROUND( m_sheetNameSize * 1.3 ) + 8 ) );
502  end.y += KiROUND( m_fileNameSize * 1.3 ) + 8;
503 
504  box.SetEnd( end );
505  box.Inflate( lineWidth / 2 );
506 
507  return box;
508 }
509 
510 
512 {
513  EDA_RECT box( m_pos, m_size );
514  return box.GetCenter();
515 }
516 
517 
519 {
520  int n = 0;
521 
522  if( m_screen )
523  {
524  for( auto aItem : m_screen->Items().OfType( SCH_COMPONENT_T ) )
525  {
526  SCH_COMPONENT* Cmp = (SCH_COMPONENT*) aItem;
527 
528  if( Cmp->GetField( VALUE )->GetText().GetChar( 0 ) != '#' )
529  n++;
530  }
531 
532  for( auto aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
533  n += static_cast<const SCH_SHEET*>( aItem )->ComponentCount();
534  }
535 
536  return n;
537 }
538 
539 
540 bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
541 {
542  if( m_screen )
543  {
544  // Only check the root sheet once and don't recurse.
545  if( !GetParent() )
546  {
547  if( m_screen && m_screen->GetFileName().Cmp( aFilename ) == 0 )
548  {
549  *aScreen = m_screen;
550  return true;
551  }
552  }
553 
554  for( auto aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
555  {
556  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
557  SCH_SCREEN* screen = sheet->m_screen;
558 
559  // Must use the screen's path (which is always absolute) rather than the
560  // sheet's (which could be relative).
561  if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
562  {
563  *aScreen = screen;
564  return true;
565  }
566 
567  if( sheet->SearchHierarchy( aFilename, aScreen ) )
568  return true;
569  }
570  }
571 
572  return false;
573 }
574 
575 
577 {
578  if( m_screen )
579  {
580  aList->push_back( this );
581 
582  if( m_screen == aScreen )
583  return true;
584 
585  for( auto item : m_screen->Items().OfType( SCH_SHEET_T ) )
586  {
587  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
588 
589  if( sheet->LocatePathOfScreen( aScreen, aList ) )
590  {
591  return true;
592  }
593  }
594 
595  aList->pop_back();
596  }
597 
598  return false;
599 }
600 
601 
603 {
604  int count = 1; //1 = this!!
605 
606  if( m_screen )
607  {
608  for( auto aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
609  count += static_cast<SCH_SHEET*>( aItem )->CountSheets();
610  }
611 
612  return count;
613 }
614 
615 
616 wxString SCH_SHEET::GetFileName( void ) const
617 {
618  return m_fileName;
619 }
620 
621 
623 {
624  aList.push_back( MSG_PANEL_ITEM( _( "Sheet Name" ), m_name, CYAN ) );
625  aList.push_back( MSG_PANEL_ITEM( _( "File Name" ), m_fileName, BROWN ) );
626 
627 #if 0 // Set to 1 to display the sheet time stamp (mainly for test)
628  wxString msg;
629  msg.Printf( wxT( "%.8X" ), m_TimeStamp );
630  aList.push_back( MSG_PANEL_ITEM( _( "Time Stamp" ), msg, BLUE ) );
631 #endif
632 }
633 
634 
635 void SCH_SHEET::Rotate(wxPoint aPosition)
636 {
637  RotatePoint( &m_pos, aPosition, 900 );
638  RotatePoint( &m_size.x, &m_size.y, 900 );
639 
640  if( m_size.x < 0 )
641  {
642  m_pos.x += m_size.x;
643  m_size.x = -m_size.x;
644  }
645 
646  if( m_size.y < 0 )
647  {
648  m_pos.y += m_size.y;
649  m_size.y = -m_size.y;
650  }
651 
652  for( SCH_SHEET_PIN* sheetPin : m_pins )
653  sheetPin->Rotate( aPosition );
654 }
655 
656 
657 void SCH_SHEET::MirrorX( int aXaxis_position )
658 {
659  MIRROR( m_pos.y, aXaxis_position );
660  m_pos.y -= m_size.y;
661 
662  for( SCH_SHEET_PIN* sheetPin : m_pins )
663  sheetPin->MirrorX( aXaxis_position );
664 }
665 
666 
667 void SCH_SHEET::MirrorY( int aYaxis_position )
668 {
669  MIRROR( m_pos.x, aYaxis_position );
670  m_pos.x -= m_size.x;
671 
672  for( SCH_SHEET_PIN* sheetPin : m_pins )
673  sheetPin->MirrorY( aYaxis_position );
674 }
675 
676 void SCH_SHEET::SetPosition( const wxPoint& aPosition )
677 {
678  // Remember the sheet and all pin sheet positions must be
679  // modified. So use Move function to do that.
680  Move( aPosition - m_pos );
681 }
682 
683 
684 
685 void SCH_SHEET::Resize( const wxSize& aSize )
686 {
687  if( aSize == m_size )
688  return;
689 
690  m_size = aSize;
691 
692  /* Move the sheet labels according to the new sheet size. */
693  for( SCH_SHEET_PIN* sheetPin : m_pins )
694  sheetPin->ConstrainOnEdge( sheetPin->GetPosition() );
695 }
696 
697 
698 bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData )
699 {
700  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
701 
702  // Ignore the sheet file name if searching to replace.
703  if( !(aSearchData.GetFlags() & FR_SEARCH_REPLACE)
704  && SCH_ITEM::Matches( m_fileName, aSearchData ) )
705  {
706  return true;
707  }
708 
709  if( SCH_ITEM::Matches( m_name, aSearchData ) )
710  {
711  return true;
712  }
713 
714  return false;
715 }
716 
717 
718 bool SCH_SHEET::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
719 {
720  return EDA_ITEM::Replace( aSearchData, m_name );
721 }
722 
723 
725 {
726  int id = 2;
727 
728  for( SCH_SHEET_PIN* pin : m_pins )
729  {
730  pin->SetNumber( id );
731  id++;
732  }
733 }
734 
735 
736 void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
737 {
738  for( SCH_SHEET_PIN* sheetPin : m_pins )
739  {
740  wxCHECK2_MSG( sheetPin->Type() == SCH_SHEET_PIN_T, continue,
741  wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
742 
743  sheetPin->GetEndPoints( aItemList );
744  }
745 }
746 
747 
748 bool SCH_SHEET::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
749 {
750  bool changed = false;
751 
752  for( SCH_SHEET_PIN* sheetPin : m_pins )
753  changed |= sheetPin->UpdateDanglingState( aItemList );
754 
755  return changed;
756 }
757 
758 
759 void SCH_SHEET::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
760 {
761  for( SCH_SHEET_PIN* sheetPin : m_pins )
762  aPoints.push_back( sheetPin->GetPosition() );
763 }
764 
765 
766 SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICAD_T aFilterTypes[] )
767 {
768  KICAD_T stype;
769 
770  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
771  {
772  // If caller wants to inspect my type
773  if( stype == SCH_LOCATE_ANY_T || stype == Type() )
774  {
775  if( SEARCH_RESULT::QUIT == aInspector( this, NULL ) )
776  return SEARCH_RESULT::QUIT;
777  }
778 
779  if( stype == SCH_LOCATE_ANY_T || stype == SCH_SHEET_PIN_T )
780  {
781  // Test the sheet labels.
782  for( SCH_SHEET_PIN* sheetPin : m_pins )
783  {
784  if( SEARCH_RESULT::QUIT == aInspector( sheetPin, this ) )
785  return SEARCH_RESULT::QUIT;
786  }
787  }
788  }
789 
791 }
792 
793 
794 wxString SCH_SHEET::GetSelectMenuText( EDA_UNITS aUnits ) const
795 {
796  return wxString::Format( _( "Hierarchical Sheet %s" ), m_name );
797 }
798 
799 
801 {
803 }
804 
805 
806 bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
807 {
808  EDA_RECT rect = GetBoundingBox();
809 
810  rect.Inflate( aAccuracy );
811 
812  return rect.Contains( aPosition );
813 }
814 
815 
816 bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
817 {
818  EDA_RECT rect = aRect;
819 
820  rect.Inflate( aAccuracy );
821 
822  if( aContained )
823  return rect.Contains( GetBoundingBox() );
824 
825  return rect.Intersects( GetBoundingBox() );
826 }
827 
828 
830  SCH_SHEET_PATH* aSheetPath )
831 {
832  SCH_SHEET_PATH sheetPath = *aSheetPath;
833  sheetPath.push_back( this );
834 
835  for( SCH_SHEET_PIN* sheetPin : m_pins )
836  {
837  NETLIST_OBJECT* item = new NETLIST_OBJECT();
838  item->m_SheetPathInclude = sheetPath;
839  item->m_SheetPath = *aSheetPath;
840  item->m_Comp = sheetPin;
841  item->m_Link = this;
843  item->m_Label = sheetPin->GetText();
844  item->m_Start = item->m_End = sheetPin->GetPosition();
845  aNetListItems.push_back( item );
846 
847  SCH_CONNECTION conn;
848  if( conn.IsBusLabel( sheetPin->GetText() ) )
849  item->ConvertBusToNetListItems( aNetListItems );
850  }
851 }
852 
853 
854 void SCH_SHEET::Plot( PLOTTER* aPlotter )
855 {
856  COLOR4D txtcolor = COLOR4D::UNSPECIFIED;
857  wxSize size;
858  wxString Text;
859  int name_orientation;
860  wxPoint pos_sheetname, pos_filename;
861  wxPoint pos;
862 
863  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
864 
865  int thickness = GetPenSize();
866  aPlotter->SetCurrentLineWidth( thickness );
867 
868  aPlotter->MoveTo( m_pos );
869  pos = m_pos;
870  pos.x += m_size.x;
871 
872  aPlotter->LineTo( pos );
873  pos.y += m_size.y;
874 
875  aPlotter->LineTo( pos );
876  pos = m_pos;
877  pos.y += m_size.y;
878 
879  aPlotter->LineTo( pos );
880  aPlotter->FinishTo( m_pos );
881 
882  if( IsVerticalOrientation() )
883  {
884  pos_sheetname = wxPoint( m_pos.x - 8, m_pos.y + m_size.y );
885  pos_filename = wxPoint( m_pos.x + m_size.x + 4, m_pos.y + m_size.y );
886  name_orientation = TEXT_ANGLE_VERT;
887  }
888  else
889  {
890  pos_sheetname = wxPoint( m_pos.x, m_pos.y - 4 );
891  pos_filename = wxPoint( m_pos.x, m_pos.y + m_size.y + 4 );
892  name_orientation = TEXT_ANGLE_HORIZ;
893  }
894 
895  /* Draw texts: SheetName */
896  Text = m_name;
897  size = wxSize( m_sheetNameSize, m_sheetNameSize );
898 
899  //pos = m_pos; pos.y -= 4;
900  thickness = GetDefaultLineThickness();
901  thickness = Clamp_Text_PenSize( thickness, size, false );
902 
903  aPlotter->SetColor( GetLayerColor( LAYER_SHEETNAME ) );
904 
905  bool italic = false;
906  aPlotter->Text( pos_sheetname, txtcolor, wxT( "Sheet: " ) + Text, name_orientation, size,
908  thickness, italic, false );
909 
910  /*Draw texts : FileName */
911  Text = GetFileName();
912  size = wxSize( m_fileNameSize, m_fileNameSize );
913  thickness = GetDefaultLineThickness();
914  thickness = Clamp_Text_PenSize( thickness, size, false );
915 
917 
918  aPlotter->Text( pos_filename, txtcolor, wxT( "File: " ) + Text, name_orientation, size,
920  thickness, italic, false );
921 
922  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
923 
924  /* Draw texts : SheetLabel */
925  for( SCH_SHEET_PIN* sheetPin : m_pins )
926  sheetPin->Plot( aPlotter );
927 }
928 
929 
931 {
932  wxLogDebug( wxT( "Sheet assignment operator." ) );
933 
934  wxCHECK_MSG( Type() == aItem.Type(), *this,
935  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
936  GetClass() );
937 
938  if( &aItem != this )
939  {
940  SCH_ITEM::operator=( aItem );
941 
942  SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
943 
944  m_pos = sheet->m_pos;
945  m_size = sheet->m_size;
946  m_name = sheet->m_name;
949 
950  for( SCH_SHEET_PIN* pin : sheet->m_pins )
951  {
952  m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) );
953  m_pins.back()->SetParent( this );
954  }
955  }
956 
957  return *this;
958 }
959 
960 
961 #if defined(DEBUG)
962 
963 void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
964 {
965  // XML output:
966  wxString s = GetClass();
967 
968  NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
969  << TO_UTF8( m_name ) << '"' << ">\n";
970 
971  // show all the pins, and check the linked list integrity
972  for( SCH_SHEET_PIN* sheetPin : m_pins )
973  sheetPin->Show( nestLevel + 1, os );
974 
975  NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
976 }
977 
978 #endif
Definition: colors.h:57
#define TEXT_ANGLE_HORIZ
void FinishTo(const wxPoint &pos)
Definition: plotter.h:270
EDA_UNITS
Definition: common.h:72
SCH_LAYER_ID m_Layer
Definition: sch_item.h:141
const wxString & GetFileName() const
Definition: sch_screen.h:157
void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers returns the layers the item is drawn on (which may be more than its "home" lay...
Definition: sch_sheet.cpp:426
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:540
SCH_SHEET_PIN * GetPin(const wxPoint &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:370
timestamp_t m_TimeStamp
Time stamp used for logical links.
Definition: base_struct.h:178
PNG memory record (file in memory).
Definition: bitmap_def.h:29
#define TEXT_ANGLE_VERT
SCH_SHEET_PATH m_SheetPathInclude
static bool Replace(wxFindReplaceData &aSearchData, wxString &aText)
Helper function used in search and replace dialog Function Replace performs a text replace on aText u...
virtual void SetColor(COLOR4D color)=0
static bool IsBusLabel(const wxString &aLabel)
Test if aLabel has a bus notation.
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points.
Definition: sch_sheet.cpp:736
bool Matches(wxFindReplaceData &aSearchData, void *aAuxData) override
Function Matches compares the item against the search criteria in aSearchData.
Definition: sch_sheet.cpp:698
int CountSheets()
Count the number of sheets found in "this" sheet includeing all of the subsheets.
Definition: sch_sheet.cpp:602
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
friend class SCH_SHEET_PIN
Definition: sch_sheet.h:208
int color
Definition: DXF_plotter.cpp:61
int m_sheetNameSize
The height of the text used to draw the sheet name.
Definition: sch_sheet.h:226
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i....
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:111
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
int GetWidth() const
Definition: eda_rect.h:119
wxSize m_size
The size of the sheet.
Definition: sch_sheet.h:235
wxString m_name
This is equivalent to the reference designator for components and is stored in F0 sheet pin in the sc...
Definition: sch_sheet.h:223
SCH_SHEET * GetRootSheet()
Return the root sheet of this SCH_SHEET object.
Definition: sch_sheet.cpp:143
SCH_SHEET_PATH m_SheetPath
int GraphicTextWidth(const wxString &aText, const wxSize &aSize, bool aItalic, bool aBold)
Function GraphicTextWidth.
Definition: gr_text.cpp:107
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: sch_sheet.cpp:794
void Print(wxDC *aDC, const wxPoint &aOffset) override
Function Print Print a schematic item.
Definition: sch_sheet.cpp:436
int GetPenSize() const override
Function GetPenSize virtual pure.
Definition: sch_sheet.cpp:382
wxPoint m_pos
The position of the sheet.
Definition: sch_sheet.h:232
EDA_ITEM * m_Comp
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
Definition: sch_sheet.cpp:179
bool Contains(const wxPoint &aPoint) const
Function Contains.
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
#define MIN_SHEET_WIDTH
Definition: sch_sheet.h:42
int GetBottom() const
Definition: eda_rect.h:124
void pop_back()
Forwarded method from std::vector.
wxString m_fileName
The file name is also in the SCH_SCREEN object associated with the sheet.
Definition: sch_sheet.h:219
NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected items in a...
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
virtual void Text(const wxPoint &aPos, const COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, void *aData=NULL)
Draws text with the plotter.
Definition: gr_text.cpp:232
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:108
int GetScreenCount() const
Return the number of times the associated screen for the sheet is being used.
Definition: sch_sheet.cpp:134
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:123
void LineTo(const wxPoint &pos)
Definition: plotter.h:265
void renumberPins()
Renumber the sheet pins in the sheet.
Definition: sch_sheet.cpp:724
timestamp_t GetNewTimeStamp()
Definition: common.cpp:215
#define VALUE
wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_sheet.h:253
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:189
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:844
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize Don't allow text to become cluttered up in its own fatness.
Definition: gr_text.cpp:81
EDA_RECT const GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: sch_sheet.cpp:477
#define NULL
void MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Definition: sch_sheet.cpp:657
const BITMAP_OPAQUE add_hierarchical_subsheet_xpm[1]
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:216
void SetEnd(int x, int y)
Definition: eda_rect.h:192
std::vector< SCH_SHEET_PIN * > m_pins
The list of sheet connection points.
Definition: sch_sheet.h:215
wxString GetText(GRAPHIC_PINSHAPE aShape)
Definition: pin_shape.cpp:58
int GetRight() const
Definition: eda_rect.h:121
Definition: colors.h:59
int GetMinHeight() const
Return the minimum height that the sheet can be resized based on the sheet pin positions.
Definition: sch_sheet.cpp:305
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
Function Visit may be re-implemented for each derived class in order to handle all the types given by...
Definition: sch_sheet.cpp:766
EDA_ITEM * GetParent() const
Definition: base_struct.h:215
wxLogTrace helper definitions.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:75
SCH_SHEET_PATH.
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:344
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:635
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
int GetHeight() const
Definition: eda_rect.h:120
int ComponentCount() const
Count our own components, without the power components.
Definition: sch_sheet.cpp:518
void SetY(int val)
Definition: eda_rect.h:174
wxPoint GetFileNamePosition()
Definition: sch_sheet.cpp:407
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:206
void GRText(wxDC *aDC, const wxPoint &aPos, COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Function GRText Draw a graphic text (like module texts)
Definition: gr_text.cpp:143
wxString GetFileName(void) const
Return the filename corresponding to this sheet.
Definition: sch_sheet.cpp:616
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
Definition: sch_item.h:212
void MoveTo(const wxPoint &pos)
Definition: plotter.h:260
SCH_SHEET(const wxPoint &pos=wxPoint(0, 0))
Definition: sch_sheet.cpp:48
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
Definition: sch_sheet.cpp:759
bool HasUndefinedPins()
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:242
int GetMinWidth() const
Return the minimum width of the sheet based on the widths of the sheet pin text.
Definition: sch_sheet.cpp:265
void DecRefCount()
Definition: sch_screen.cpp:167
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:576
Base plotter engine class.
Definition: plotter.h:103
int m_fileNameSize
The height of the text used to draw the file name.
Definition: sch_sheet.h:229
void GetMsgPanelInfo(EDA_UNITS aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: sch_sheet.cpp:622
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
Definition: sch_sheet.cpp:155
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:105
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
Definition: sch_sheet.cpp:854
const wxChar *const traceFindItem
Flag to enable find debug tracing.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
#define _(s)
Definition: 3d_actions.cpp:31
bool IsVerticalOrientation() const
Definition: sch_sheet.cpp:221
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Definition: sch_sheet.cpp:667
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Definition: sch_sheet.cpp:676
wxPoint GetSheetNamePosition()
Definition: sch_sheet.cpp:388
EE_RTREE & Items()
Definition: sch_screen.h:127
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:89
SCH_SCREEN * m_screen
Screen that contains the physical data for the sheet.
Definition: sch_sheet.h:212
int GetY() const
Definition: eda_rect.h:112
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:61
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:43
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_item.h:162
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: sch_sheet.cpp:800
bool HasPin(const wxString &aName)
Checks if the sheet already has a sheet pin named aName.
Definition: sch_sheet.cpp:209
wxPoint GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:511
virtual wxString GetShownText() const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:129
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
SEARCH_RESULT
Definition: base_struct.h:54
const wxPoint GetCenter() const
Definition: eda_rect.h:117
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Definition of the NETLIST_OBJECT class.
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it's dangling state...
Definition: sch_sheet.cpp:748
Message panel definition file.
NETLIST_ITEM m_Type
bool Replace(wxFindReplaceData &aSearchData, void *aAuxData=NULL) override
Function Replace performs a text replace using the find and replace criteria in aSearchData on items ...
Definition: sch_sheet.cpp:718
SCH_ITEM * m_Link
virtual bool Matches(wxFindReplaceData &aSearchData, void *aAuxData)
Function Matches compares the item against the search criteria in aSearchData.
Definition: base_struct.h:471
SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:136
void Move(const wxPoint &aMoveVector) override
Function Move moves the item by aMoveVector to a new position.
Definition: sch_sheet.h:475
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
SCH_SHEET & operator=(const SCH_ITEM &aSheet)
Definition: sch_sheet.cpp:930
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
void IncRefCount()
Definition: sch_screen.cpp:161
void ConvertBusToNetListItems(NETLIST_OBJECT_LIST &aNetListItems)
Function ConvertBusToNetListItems breaks the text of a bus label type net list object into as many me...
int GetDefaultTextSize()
Default size for text in general.
int GetRefCount() const
Definition: sch_screen.h:170
KICAD_T Type() const
Function Type()
Definition: base_struct.h:207
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
void Resize(const wxSize &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:685
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: sch_sheet.cpp:806
void GetNetListItem(NETLIST_OBJECT_LIST &aNetListItems, SCH_SHEET_PATH *aSheetPath) override
Function GetNetListItem creates a new NETLIST_OBJECT for the schematic object and adds it to aNetList...
Definition: sch_sheet.cpp:829
Definition: colors.h:62