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