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-2017 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 <class_drawpanel.h>
32 #include <draw_graphic_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 
40 #include <sch_sheet.h>
41 #include <sch_sheet_path.h>
42 #include <sch_component.h>
43 #include <netlist_object.h>
44 #include <trace_helpers.h>
45 
46 
48  SCH_ITEM( NULL, SCH_SHEET_T )
49 {
51  m_pos = pos;
56  m_screen = NULL;
57  m_name.Printf( wxT( "Sheet%8.8lX" ), (long) m_TimeStamp );
58  m_fileName.Printf( wxT( "file%8.8lX.sch" ), (long) m_TimeStamp );
59 }
60 
61 
62 SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
63  SCH_ITEM( aSheet )
64 {
65  m_pos = aSheet.m_pos;
66  m_size = aSheet.m_size;
67  m_Layer = aSheet.m_Layer;
68  SetTimeStamp( aSheet.m_TimeStamp );
71  m_screen = aSheet.m_screen;
72  m_name = aSheet.m_name;
73  m_fileName = aSheet.m_fileName;
74  m_pins = aSheet.m_pins;
75 
76  for( size_t i = 0; i < m_pins.size(); i++ )
77  m_pins[i].SetParent( this );
78 
79  if( m_screen )
81 }
82 
83 
85 {
86  // also, look at the associated sheet & its reference count
87  // perhaps it should be deleted also.
88  if( m_screen )
89  {
91 
92  if( m_screen->GetRefCount() == 0 )
93  delete m_screen;
94  }
95 }
96 
97 
99 {
100  return new SCH_SHEET( *this );
101 }
102 
103 
105 {
106  if( aScreen == m_screen )
107  return;
108 
109  if( m_screen != NULL )
110  {
112 
113  if( m_screen->GetRefCount() == 0 )
114  {
115  delete m_screen;
116  m_screen = NULL;
117  }
118  }
119 
120  m_screen = aScreen;
121 
122  if( m_screen )
124 }
125 
126 
128 {
129  if( m_screen == NULL )
130  return 0;
131 
132  return m_screen->GetRefCount();
133 }
134 
135 
137 {
138  SCH_SHEET* sheet = dynamic_cast< SCH_SHEET* >( GetParent() );
139 
140  if( sheet == NULL )
141  return this;
142 
143  // Recurse until a sheet is found with no parent which is the root sheet.
144  return sheet->GetRootSheet();
145 }
146 
147 
149 {
150  wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
151  wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
152  GetChars( aItem->GetClass() ) ) );
153 
154  SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
155 
156  std::swap( m_pos, sheet->m_pos );
157  std::swap( m_size, sheet->m_size );
158  std::swap( m_name, sheet->m_name );
159  std::swap( m_sheetNameSize, sheet->m_sheetNameSize );
160  std::swap( m_fileNameSize, sheet->m_fileNameSize );
161  m_pins.swap( sheet->m_pins );
162 
163  // Ensure sheet labels have their .m_Parent member pointing really on their
164  // parent, after swapping.
165  for( SCH_SHEET_PIN& sheetPin : m_pins )
166  {
167  sheetPin.SetParent( this );
168  }
169 
170  for( SCH_SHEET_PIN& sheetPin : sheet->m_pins )
171  {
172  sheetPin.SetParent( sheet );
173  }
174 }
175 
176 
178 {
179  wxASSERT( aSheetPin != NULL );
180  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
181 
182  m_pins.push_back( aSheetPin );
183  renumberPins();
184 }
185 
186 
188 {
189  wxASSERT( aSheetPin != NULL );
190  wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
191 
192  SCH_SHEET_PINS::iterator i;
193 
194  for( 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( const 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  for( const SCH_SHEET_PIN& pin : m_pins )
224  {
225  if( pin.GetEdge() > 1 )
226  return true;
227  }
228  return false;
229 }
230 
231 
233 {
234  for( const SCH_SHEET_PIN& pin : m_pins )
235  {
236  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
237  EDA_ITEM* DrawStruct = m_screen->GetDrawItems();
238  const SCH_HIERLABEL* HLabel = NULL;
239 
240  for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
241  {
242  if( DrawStruct->Type() != SCH_HIERARCHICAL_LABEL_T )
243  continue;
244 
245  HLabel = static_cast<SCH_HIERLABEL*>( DrawStruct );
246 
247  if( pin.GetText().CmpNoCase( HLabel->GetText() ) == 0 )
248  break; // Found!
249 
250  HLabel = NULL;
251  }
252 
253  if( HLabel == NULL ) // Corresponding hierarchical label not found.
254  return true;
255  }
256 
257  return false;
258 }
259 
260 
262 {
263  int width = MIN_SHEET_WIDTH;
264 
265  for( size_t i = 0; i < m_pins.size(); i++ )
266  {
267  int edge = m_pins[i].GetEdge();
268  EDA_RECT pinRect = m_pins[i].GetBoundingBox();
269 
270  wxASSERT( edge != SCH_SHEET_PIN::SHEET_UNDEFINED_SIDE );
271 
273  {
274  if( width < pinRect.GetRight() - m_pos.x )
275  width = pinRect.GetRight() - m_pos.x;
276  }
277  else
278  {
279  if( width < pinRect.GetWidth() )
280  width = pinRect.GetWidth();
281 
282  for( size_t j = 0; j < m_pins.size(); j++ )
283  {
284  // Check for pin directly across from the current pin.
285  if( (i == j) || (m_pins[i].GetPosition().y != m_pins[j].GetPosition().y) )
286  continue;
287 
288  if( width < pinRect.GetWidth() + m_pins[j].GetBoundingBox().GetWidth() )
289  {
290  width = pinRect.GetWidth() + m_pins[j].GetBoundingBox().GetWidth();
291  break;
292  }
293  }
294  }
295  }
296 
297  return width;
298 }
299 
300 
302 {
303  int height = MIN_SHEET_HEIGHT;
304 
305  for( size_t i = 0; i < m_pins.size(); i++ )
306  {
307  int edge = m_pins[i].GetEdge();
308  EDA_RECT pinRect = m_pins[i].GetBoundingBox();
309 
310  // Make sure pin is on top or bottom side of sheet.
312  {
313  if( height < pinRect.GetBottom() - m_pos.y )
314  height = pinRect.GetBottom() - m_pos.y;
315  }
316  else
317  {
318  if( height < pinRect.GetHeight() )
319  height = pinRect.GetHeight();
320 
321  for( size_t j = 0; j < m_pins.size(); j++ )
322  {
323  // Check for pin directly above or below the current pin.
324  if( (i == j) || (m_pins[i].GetPosition().x != m_pins[j].GetPosition().x) )
325  continue;
326 
327  if( height < pinRect.GetHeight() + m_pins[j].GetBoundingBox().GetHeight() )
328  {
329  height = pinRect.GetHeight() + m_pins[j].GetBoundingBox().GetHeight();
330  break;
331  }
332  }
333  }
334  }
335 
336  return height;
337 }
338 
339 
341 {
342  SCH_SHEET_PINS::iterator i = m_pins.begin();
343 
344  while( i != m_pins.end() )
345  {
346  /* Search the schematic for a hierarchical label corresponding to this sheet label. */
347  EDA_ITEM* DrawStruct = m_screen->GetDrawItems();
348  const SCH_HIERLABEL* HLabel = NULL;
349 
350  for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
351  {
352  if( DrawStruct->Type() != SCH_HIERARCHICAL_LABEL_T )
353  continue;
354 
355  HLabel = static_cast<SCH_HIERLABEL*>( DrawStruct );
356 
357  if( i->GetText().CmpNoCase( HLabel->GetText() ) == 0 )
358  break; // Found!
359 
360  HLabel = NULL;
361  }
362 
363  if( HLabel == NULL ) // Hlabel not found: delete sheet label.
364  i = m_pins.erase( i );
365  else
366  ++i;
367  }
368 }
369 
370 
372 {
373  for( SCH_SHEET_PIN& pin : m_pins )
374  {
375  if( pin.HitTest( aPosition, 0 ) )
376  return &pin;
377  }
378 
379  return NULL;
380 }
381 
382 
384 {
385  return GetDefaultLineThickness();
386 }
387 
388 
390 {
391  wxPoint pos = m_pos;
392 
393  if( IsVerticalOrientation() )
394  {
395  pos.x -= 8;
396  pos.y += m_size.y;
397  }
398  else
399  {
400  pos.y -= 8;
401  }
402 
403  return pos;
404 }
405 
406 
408 {
409  wxPoint pos = m_pos;
410  int margin = GetPenSize() + 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::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
427  const wxPoint& aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor )
428 {
429  COLOR4D txtcolor;
430  wxString Text;
431  COLOR4D color;
432  int name_orientation;
433  wxPoint pos_sheetname,pos_filename;
434  wxPoint pos = m_pos + aOffset;
435  int lineWidth = GetPenSize();
436  EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
437 
438  if( aColor != COLOR4D::UNSPECIFIED )
439  color = aColor;
440  else
441  color = GetLayerColor( m_Layer );
442 
443  GRSetDrawMode( aDC, aDrawMode );
444 
445  GRRect( clipbox, aDC, pos.x, pos.y,
446  pos.x + m_size.x, pos.y + m_size.y, lineWidth, color );
447 
448  pos_sheetname = GetSheetNamePosition() + aOffset;
449  pos_filename = GetFileNamePosition() + aOffset;
450 
451  if( IsVerticalOrientation() )
452  name_orientation = TEXT_ANGLE_VERT;
453  else
454  name_orientation = TEXT_ANGLE_HORIZ;
455 
456  /* Draw text : SheetName */
457  if( aColor != COLOR4D::UNSPECIFIED )
458  txtcolor = aColor;
459  else
460  txtcolor = GetLayerColor( LAYER_SHEETNAME );
461 
462  Text = wxT( "Sheet: " ) + m_name;
463  DrawGraphicText( clipbox, aDC, pos_sheetname,
464  txtcolor, Text, name_orientation,
465  wxSize( m_sheetNameSize, m_sheetNameSize ),
467  false, false );
468 
469  /* Draw text : FileName */
470  if( aColor != COLOR4D::UNSPECIFIED )
471  txtcolor = aColor;
472  else
473  txtcolor = GetLayerColor( LAYER_SHEETFILENAME );
474 
475  Text = wxT( "File: " ) + m_fileName;
476  DrawGraphicText( clipbox, aDC, pos_filename,
477  txtcolor, Text, name_orientation,
478  wxSize( m_fileNameSize, m_fileNameSize ),
480  false, false );
481 
482  /* Draw text : SheetLabel */
483  for( SCH_SHEET_PIN& sheetPin : m_pins )
484  {
485  if( !sheetPin.IsMoving() )
486  sheetPin.Draw( aPanel, aDC, aOffset, aDrawMode, aColor );
487  }
488 
489 
490 #if 0
491  // Only for testing purposes, draw the component bounding box
493  GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
494  GRFilledCircle( aPanel->GetClipBox(), aDC, m_pos.x, m_pos.y, 10, 0, color, color );
495 #endif
496 }
497 
498 
500 {
501  wxPoint end;
502  EDA_RECT box( m_pos, m_size );
503  int lineWidth = GetPenSize();
504 
505  // Determine length of texts
506  wxString text = wxT( "Sheet: " ) + m_name;
507  int textlen = GraphicTextWidth( text, wxSize( m_sheetNameSize, m_sheetNameSize ),
508  false, false );
509 
510  text = wxT( "File: " ) + m_fileName;
511  int textlen2 = GraphicTextWidth( text, wxSize( m_fileNameSize, m_fileNameSize ),
512  false, false );
513 
514  // Calculate bounding box X size:
515  textlen = std::max( textlen, textlen2 );
516  end.x = std::max( m_size.x, textlen );
517 
518  // Calculate bounding box pos:
519  end.y = m_size.y;
520  end += m_pos;
521 
522  // Move upper and lower limits to include texts:
523  box.SetY( box.GetY() - ( KiROUND( m_sheetNameSize * 1.3 ) + 8 ) );
524  end.y += KiROUND( m_fileNameSize * 1.3 ) + 8;
525 
526  box.SetEnd( end );
527  box.Inflate( lineWidth / 2 );
528 
529  return box;
530 }
531 
532 
534 {
535  int n = 0;
536 
537  if( m_screen )
538  {
539  EDA_ITEM* bs;
540 
541  for( bs = m_screen->GetDrawItems(); bs != NULL; bs = bs->Next() )
542  {
543  if( bs->Type() == SCH_COMPONENT_T )
544  {
545  SCH_COMPONENT* Cmp = (SCH_COMPONENT*) bs;
546 
547  if( Cmp->GetField( VALUE )->GetText().GetChar( 0 ) != '#' )
548  n++;
549  }
550 
551  if( bs->Type() == SCH_SHEET_T )
552  {
553  SCH_SHEET* sheet = (SCH_SHEET*) bs;
554  n += sheet->ComponentCount();
555  }
556  }
557  }
558 
559  return n;
560 }
561 
562 
563 bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
564 {
565  if( m_screen )
566  {
567  EDA_ITEM* item = m_screen->GetDrawItems();
568 
569  while( item )
570  {
571  if( item->Type() == SCH_SHEET_T )
572  {
573  SCH_SHEET* sheet = (SCH_SHEET*) item;
574 
575  if( sheet->m_screen
576  && sheet->m_screen->GetFileName().CmpNoCase( aFilename ) == 0 )
577  {
578  *aScreen = sheet->m_screen;
579  return true;
580  }
581 
582  if( sheet->SearchHierarchy( aFilename, aScreen ) )
583  return true;
584  }
585 
586  item = item->Next();
587  }
588  }
589 
590  return false;
591 }
592 
593 
595 {
596  if( m_screen )
597  {
598  aList->push_back( this );
599 
600  if( m_screen == aScreen )
601  return true;
602 
603  EDA_ITEM* strct = m_screen->GetDrawItems();
604 
605  while( strct )
606  {
607  if( strct->Type() == SCH_SHEET_T )
608  {
609  SCH_SHEET* ss = (SCH_SHEET*) strct;
610 
611  if( ss->LocatePathOfScreen( aScreen, aList ) )
612  return true;
613  }
614 
615  strct = strct->Next();
616  }
617 
618  aList->pop_back();
619  }
620 
621  return false;
622 }
623 
624 
626 {
627  int count = 1; //1 = this!!
628 
629  if( m_screen )
630  {
631  EDA_ITEM* strct = m_screen->GetDrawItems();
632 
633  for( ; strct; strct = strct->Next() )
634  {
635  if( strct->Type() == SCH_SHEET_T )
636  {
637  SCH_SHEET* subsheet = (SCH_SHEET*) strct;
638  count += subsheet->CountSheets();
639  }
640  }
641  }
642  return count;
643 }
644 
645 
646 wxString SCH_SHEET::GetFileName( void ) const
647 {
648  return m_fileName;
649 }
650 
651 
653 {
654  aList.push_back( MSG_PANEL_ITEM( _( "Sheet Name" ), m_name, CYAN ) );
655  aList.push_back( MSG_PANEL_ITEM( _( "File Name" ), m_fileName, BROWN ) );
656 
657 #if 0 // Set to 1 to display the sheet time stamp (mainly for test)
658  wxString msg;
659  msg.Printf( wxT( "%.8X" ), m_TimeStamp );
660  aList.push_back( MSG_PANEL_ITEM( _( "Time Stamp" ), msg, BLUE ) );
661 #endif
662 }
663 
664 
665 void SCH_SHEET::Rotate(wxPoint aPosition)
666 {
667  RotatePoint( &m_pos, aPosition, 900 );
668  RotatePoint( &m_size.x, &m_size.y, 900 );
669 
670  if( m_size.x < 0 )
671  {
672  m_pos.x += m_size.x;
673  m_size.x = -m_size.x;
674  }
675 
676  if( m_size.y < 0 )
677  {
678  m_pos.y += m_size.y;
679  m_size.y = -m_size.y;
680  }
681 
682  for( SCH_SHEET_PIN& sheetPin : m_pins )
683  {
684  sheetPin.Rotate( aPosition );
685  }
686 }
687 
688 
689 void SCH_SHEET::MirrorX( int aXaxis_position )
690 {
691  MIRROR( m_pos.y, aXaxis_position );
692  m_pos.y -= m_size.y;
693 
694  for( SCH_SHEET_PIN& sheetPin : m_pins )
695  {
696  sheetPin.MirrorX( aXaxis_position );
697  }
698 }
699 
700 
701 void SCH_SHEET::MirrorY( int aYaxis_position )
702 {
703  MIRROR( m_pos.x, aYaxis_position );
704  m_pos.x -= m_size.x;
705 
706  for( SCH_SHEET_PIN& label : m_pins )
707  {
708  label.MirrorY( aYaxis_position );
709  }
710 }
711 
712 void SCH_SHEET::SetPosition( const wxPoint& aPosition )
713 {
714  // Remember the sheet and all pin sheet positions must be
715  // modified. So use Move function to do that.
716  Move( aPosition - m_pos );
717 }
718 
719 
720 
721 void SCH_SHEET::Resize( const wxSize& aSize )
722 {
723  if( aSize == m_size )
724  return;
725 
726  m_size = aSize;
727 
728  /* Move the sheet labels according to the new sheet size. */
729  for( SCH_SHEET_PIN& label : m_pins )
730  {
731  label.ConstrainOnEdge( label.GetPosition() );
732  }
733 }
734 
735 
736 bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
737 {
738  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
739 
740  // Ignore the sheet file name if searching to replace.
741  if( !(aSearchData.GetFlags() & FR_SEARCH_REPLACE)
742  && SCH_ITEM::Matches( m_fileName, aSearchData ) )
743  {
744  if( aFindLocation )
745  *aFindLocation = GetFileNamePosition();
746 
747  return true;
748  }
749 
750  if( SCH_ITEM::Matches( m_name, aSearchData ) )
751  {
752  if( aFindLocation )
753  *aFindLocation = GetSheetNamePosition();
754 
755  return true;
756  }
757 
758  return false;
759 }
760 
761 
762 bool SCH_SHEET::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
763 {
764  return EDA_ITEM::Replace( aSearchData, m_name );
765 }
766 
767 
769 {
770  int id = 2;
771 
772  for( SCH_SHEET_PIN& pin : m_pins )
773  {
774  pin.SetNumber( id );
775  id++;
776  }
777 }
778 
779 
780 void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
781 {
782  for( unsigned ii = 0; ii < GetPins().size(); ii++ )
783  {
784  SCH_SHEET_PIN &pinsheet = GetPins()[ii];
785 
786  wxCHECK2_MSG( pinsheet.Type() == SCH_SHEET_PIN_T, continue,
787  wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
788 
789  pinsheet.GetEndPoints( aItemList );
790  }
791 }
792 
793 
794 bool SCH_SHEET::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
795 {
796  bool currentState = IsDangling();
797 
798  for( SCH_SHEET_PIN& pinsheet : GetPins() )
799  {
800  pinsheet.IsDanglingStateChanged( aItemList );
801  }
802 
803  return currentState != IsDangling();
804 }
805 
806 
808 {
809  // If any hierarchical label in the sheet is dangling, then the sheet is dangling.
810  for( size_t i = 0; i < GetPins().size(); i++ )
811  {
812  if( GetPins()[i].IsDangling() )
813  return true;
814  }
815 
816  return false;
817 }
818 
819 
820 bool SCH_SHEET::IsSelectStateChanged( const wxRect& aRect )
821 {
822  bool previousState = IsSelected();
823 
825 
826  if( aRect.Intersects( boundingBox ) )
827  SetFlags( SELECTED );
828  else
829  ClearFlags( SELECTED );
830 
831  return previousState != IsSelected();
832 }
833 
834 
835 void SCH_SHEET::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
836 {
837  for( size_t i = 0; i < GetPins().size(); i++ )
838  aPoints.push_back( GetPins()[i].GetPosition() );
839 }
840 
841 
842 SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICAD_T aFilterTypes[] )
843 {
844  KICAD_T stype;
845 
846  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
847  {
848  // If caller wants to inspect my type
849  if( stype == Type() )
850  {
851  if( SEARCH_QUIT == aInspector( this, NULL ) )
852  return SEARCH_QUIT;
853  }
854  else if( stype == SCH_SHEET_PIN_T )
855  {
856  // Test the sheet labels.
857  for( size_t i = 0; i < m_pins.size(); i++ )
858  {
859  if( SEARCH_QUIT == aInspector( &m_pins[ i ], this ) )
860  return SEARCH_QUIT;
861  }
862  }
863  }
864 
865  return SEARCH_CONTINUE;
866 }
867 
868 
870 {
871  wxString tmp;
872  tmp.Printf( _( "Hierarchical Sheet %s" ), GetChars( m_name ) );
873  return tmp;
874 }
875 
876 
878 {
879  return add_hierarchical_subsheet_xpm;
880 }
881 
882 
883 bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
884 {
885  EDA_RECT rect = GetBoundingBox();
886 
887  rect.Inflate( aAccuracy );
888 
889  return rect.Contains( aPosition );
890 }
891 
892 
893 bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
894 {
895  EDA_RECT rect = aRect;
896 
897  rect.Inflate( aAccuracy );
898 
899  if( aContained )
900  return rect.Contains( GetBoundingBox() );
901 
902  return rect.Intersects( GetBoundingBox() );
903 }
904 
905 
907 {
908  return wxPoint( m_pos.x + m_size.GetWidth(), m_pos.y + m_size.GetHeight() );
909 }
910 
911 
913  SCH_SHEET_PATH* aSheetPath )
914 {
915  SCH_SHEET_PATH sheetPath = *aSheetPath;
916  sheetPath.push_back( this );
917 
918  for( size_t i = 0; i < m_pins.size(); i++ )
919  {
920  NETLIST_OBJECT* item = new NETLIST_OBJECT();
921  item->m_SheetPathInclude = sheetPath;
922  item->m_SheetPath = *aSheetPath;
923  item->m_Comp = &m_pins[i];
924  item->m_Link = this;
925  item->m_Type = NET_SHEETLABEL;
926  item->m_Label = m_pins[i].GetText();
927  item->m_Start = item->m_End = m_pins[i].GetPosition();
928  aNetListItems.push_back( item );
929 
930  if( IsBusLabel( m_pins[i].GetText() ) )
931  item->ConvertBusToNetListItems( aNetListItems );
932  }
933 }
934 
935 
936 void SCH_SHEET::Plot( PLOTTER* aPlotter )
937 {
938  COLOR4D txtcolor = COLOR4D::UNSPECIFIED;
939  wxSize size;
940  wxString Text;
941  int name_orientation;
942  wxPoint pos_sheetname, pos_filename;
943  wxPoint pos;
944 
945  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
946 
947  int thickness = GetPenSize();
948  aPlotter->SetCurrentLineWidth( thickness );
949 
950  aPlotter->MoveTo( m_pos );
951  pos = m_pos;
952  pos.x += m_size.x;
953 
954  aPlotter->LineTo( pos );
955  pos.y += m_size.y;
956 
957  aPlotter->LineTo( pos );
958  pos = m_pos;
959  pos.y += m_size.y;
960 
961  aPlotter->LineTo( pos );
962  aPlotter->FinishTo( m_pos );
963 
964  if( IsVerticalOrientation() )
965  {
966  pos_sheetname = wxPoint( m_pos.x - 8, m_pos.y + m_size.y );
967  pos_filename = wxPoint( m_pos.x + m_size.x + 4, m_pos.y + m_size.y );
968  name_orientation = TEXT_ANGLE_VERT;
969  }
970  else
971  {
972  pos_sheetname = wxPoint( m_pos.x, m_pos.y - 4 );
973  pos_filename = wxPoint( m_pos.x, m_pos.y + m_size.y + 4 );
974  name_orientation = TEXT_ANGLE_HORIZ;
975  }
976 
977  /* Draw texts: SheetName */
978  Text = m_name;
979  size = wxSize( m_sheetNameSize, m_sheetNameSize );
980 
981  //pos = m_pos; pos.y -= 4;
982  thickness = GetDefaultLineThickness();
983  thickness = Clamp_Text_PenSize( thickness, size, false );
984 
985  aPlotter->SetColor( GetLayerColor( LAYER_SHEETNAME ) );
986 
987  bool italic = false;
988  aPlotter->Text( pos_sheetname, txtcolor, Text, name_orientation, size,
990  thickness, italic, false );
991 
992  /*Draw texts : FileName */
993  Text = GetFileName();
994  size = wxSize( m_fileNameSize, m_fileNameSize );
995  thickness = GetDefaultLineThickness();
996  thickness = Clamp_Text_PenSize( thickness, size, false );
997 
999 
1000  aPlotter->Text( pos_filename, txtcolor, Text, name_orientation, size,
1002  thickness, italic, false );
1003 
1004  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
1005 
1006  /* Draw texts : SheetLabel */
1007  for( size_t i = 0; i < m_pins.size(); i++ )
1008  {
1009  m_pins[i].Plot( aPlotter );
1010  }
1011 }
1012 
1013 
1015 {
1016  wxLogDebug( wxT( "Sheet assignment operator." ) );
1017 
1018  wxCHECK_MSG( Type() == aItem.Type(), *this,
1019  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1020  GetClass() );
1021 
1022  if( &aItem != this )
1023  {
1024  SCH_ITEM::operator=( aItem );
1025 
1026  SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
1027 
1028  m_pos = sheet->m_pos;
1029  m_size = sheet->m_size;
1030  m_name = sheet->m_name;
1032  m_fileNameSize = sheet->m_fileNameSize;
1033  m_pins = sheet->m_pins;
1034 
1035  // Ensure sheet labels have their #m_Parent member pointing really on their
1036  // parent, after assigning.
1037  for( SCH_SHEET_PIN& sheetPin : m_pins )
1038  {
1039  sheetPin.SetParent( this );
1040  }
1041  }
1042 
1043  return *this;
1044 }
1045 
1046 
1047 #if defined(DEBUG)
1048 
1049 void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
1050 {
1051  // XML output:
1052  wxString s = GetClass();
1053 
1054  NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
1055  << TO_UTF8( m_name ) << '"' << ">\n";
1056 
1057  // show all the pins, and check the linked list integrity
1058  for( const SCH_SHEET_PIN& label : m_pins )
1059  {
1060  label.Show( nestLevel + 1, os );
1061  }
1062 
1063  NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
1064 }
1065 
1066 #endif
Definition: colors.h:57
void FinishTo(const wxPoint &pos)
Definition: plotter.h:250
Definition of the SCH_SHEET class for Eeschema.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Definition: common.h:91
SCH_LAYER_ID m_Layer
SCH_ITEM & operator=(const SCH_ITEM &aSheet)
Definition: sch_sheet.cpp:1014
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize As a rule, pen width should not be >1/4em, otherwise the character will b...
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:563
SCH_SHEET_PIN * GetPin(const wxPoint &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:371
bool IsDangling() const override
Definition: sch_sheet.cpp:807
timestamp_t m_TimeStamp
Time stamp used for logical links.
Definition: base_struct.h:180
SCH_SHEET_PINS & GetPins()
Definition: sch_sheet.h:334
PNG memory record (file in memory).
Definition: bitmap_types.h:41
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:318
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
SCH_SHEET_PATH m_SheetPathInclude
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
bool Contains(const wxPoint &aPoint) const
Function Contains.
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:780
int CountSheets()
Count the number of sheets found in "this" sheet includeing all of the subsheets. ...
Definition: sch_sheet.cpp:625
int GetMinHeight() const
Return the minimum height that the sheet can be resized based on the sheet pin positions.
Definition: sch_sheet.cpp:301
virtual bool Matches(wxFindReplaceData &aSearchData, void *aAuxData, wxPoint *aFindLocation)
Function Matches compares the item against the search criteria in aSearchData.
Definition: base_struct.h:411
int color
Definition: DXF_plotter.cpp:62
int m_sheetNameSize
The height of the text used to draw the sheet name.
Definition: sch_sheet.h:229
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:104
const wxString & GetFileName() const
Definition: sch_screen.h:120
wxPoint GetResizePosition() const
Return the position of the lower right corner of the sheet in drawing units.
Definition: sch_sheet.cpp:906
bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it&#39;s dangling state...
Definition: sch_sheet.cpp:794
int GetHeight() const
Definition: eda_rect.h:118
wxSize m_size
The size of the sheet.
Definition: sch_sheet.h:238
bool IsSelected() const
Definition: base_struct.h:232
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:226
EDA_ITEM * GetParent() const
Definition: base_struct.h:219
SCH_SHEET * GetRootSheet()
Return the root sheet of this SCH_SHEET object.
Definition: sch_sheet.cpp:136
int ComponentCount()
Count our own components, without the power components.
Definition: sch_sheet.cpp:533
int GetRefCount() const
Definition: sch_screen.h:133
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
SCH_SHEET_PATH m_SheetPath
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it&#39;s internal state for displ...
Definition: sch_sheet.cpp:652
EDA_ITEM * Next() const
Definition: base_struct.h:217
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
bool Matches(wxFindReplaceData &aSearchData, void *aAuxData, wxPoint *aFindLocation) override
Function Matches compares the item against the search criteria in aSearchData.
Definition: sch_sheet.cpp:736
NETLIST_ITEM_T m_Type
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:167
int GetPenSize() const override
Function GetPenSize virtual pure.
Definition: sch_sheet.cpp:383
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:873
wxPoint m_pos
The position of the sheet.
Definition: sch_sheet.h:235
EDA_ITEM * m_Comp
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
Definition: sch_sheet.cpp:177
#define TEXT_ANGLE_VERT
Definition: common.h:92
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:47
void DrawGraphicText(EDA_RECT *aClipBox, 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 DrawGraphicText Draw a graphic text (like module texts)
wxString m_fileName
The file name is also in the SCH_SCREEN object associated with the sheet.
Definition: sch_sheet.h:222
Class NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected item...
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.
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:133
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:100
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
BOX2I boundingBox(T aObject)
boundingBox template method
Definition: shape_index.h:59
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
#define SELECTED
Definition: base_struct.h:116
void LineTo(const wxPoint &pos)
Definition: plotter.h:245
void renumberPins()
Renumber the sheet pins in the sheet.
Definition: sch_sheet.cpp:768
timestamp_t GetNewTimeStamp()
Definition: common.cpp:167
wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_sheet.h:251
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:187
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1098
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:264
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
EDA_RECT const GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_sheet.cpp:499
void MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Definition: sch_sheet.cpp:689
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:224
SCH_SHEET_PINS m_pins
The list of sheet connection points.
Definition: sch_sheet.h:218
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
void SetEnd(int x, int y)
Definition: eda_rect.h:134
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
Definition: colors.h:59
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:842
int GraphicTextWidth(const wxString &aText, const wxSize &aSize, bool aItalic, bool aBold)
Function GraphicTextWidth.
EDA_RECT * GetClipBox()
wxLogTrace helper definitions.
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: sch_sheet.cpp:869
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:61
int GetBottom() const
Definition: eda_rect.h:122
Class SCH_SHEET_PATH.
int GetScreenCount() const
Return the number of times the associated screen for the sheet is being used.
Definition: sch_sheet.cpp:127
int GetRight() const
Definition: eda_rect.h:119
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:340
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_sheet.h:547
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:665
wxString GetFileName(void) const
Return the filename corresponding to this sheet.
Definition: sch_sheet.cpp:646
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
void SetY(int val)
Definition: eda_rect.h:131
bool IsBusLabel(const wxString &aLabel)
Function IsBusLabel test if aLabel has a bus notation.
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:209
void MoveTo(const wxPoint &pos)
Definition: plotter.h:240
SCH_SHEET(const wxPoint &pos=wxPoint(0, 0))
Definition: sch_sheet.cpp:47
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
Definition: sch_sheet.cpp:835
bool HasUndefinedPins()
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:232
void DecRefCount()
Definition: sch_screen.cpp:130
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:594
Base plotter engine class.
Definition: plotter.h:96
SCH_ITEM * GetDrawItems() const
Definition: sch_screen.h:138
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED) override
Function Draw Draw a schematic item.
Definition: sch_sheet.cpp:426
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Definition the SCH_COMPONENT class for Eeschema.
int m_fileNameSize
The height of the text used to draw the file name.
Definition: sch_sheet.h:232
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
Definition: sch_sheet.cpp:148
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:92
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:98
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
Definition: sch_sheet.cpp:936
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
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...
#define max(a, b)
Definition: auxiliary.h:86
int GetMinWidth() const
Return the minimum width of the sheet based on the widths of the sheet pin text.
Definition: sch_sheet.cpp:261
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Definition: sch_sheet.cpp:701
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Definition: sch_sheet.cpp:712
wxPoint GetSheetNamePosition()
Definition: sch_sheet.cpp:389
size_t i
Definition: json11.cpp:597
Perform a search for a item that has replaceable text.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
SCH_SCREEN * m_screen
Screen that contains the physical data for the sheet.
Definition: sch_sheet.h:215
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:162
int GetWidth() const
Definition: eda_rect.h:117
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:48
bool IsVerticalOrientation() const
Definition: sch_sheet.cpp:221
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
int GetY() const
Definition: eda_rect.h:110
virtual wxString GetClass() const override
Function GetClass returns the class name.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: sch_sheet.cpp:877
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:265
bool HasPin(const wxString &aName)
Checks if the sheet already has a sheet pin named aName.
Definition: sch_sheet.cpp:209
Class 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:64
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Definition of the NETLIST_OBJECT class.
Message panel definition file.
bool IsSelectStateChanged(const wxRect &aRect) override
Function IsSelectStateChanged checks if the selection state of an item inside aRect has changed...
Definition: sch_sheet.cpp:820
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:762
SCH_ITEM * m_Link
#define VALUE
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
void Move(const wxPoint &aMoveVector) override
Function Move moves the item by aMoveVector to a new position.
Definition: sch_sheet.h:478
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:124
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.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:214
void Resize(const wxSize &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:721
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
Class 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:883
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:912
Definition: colors.h:62