KiCad PCB EDA Suite
sch_screen.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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
32 #include <common.h>
33 #include <eda_rect.h>
34 #include <eeschema_id.h>
35 #include <fctsys.h>
36 #include <gr_basic.h>
37 #include <gr_text.h>
38 #include <id.h>
39 #include <kicad_string.h>
40 #include <kiway.h>
41 #include <pgm_base.h>
42 #include <plotter.h>
43 #include <project.h>
44 #include <sch_draw_panel.h>
45 #include <sch_edit_frame.h>
46 #include <sch_item.h>
47 
48 #include <class_library.h>
49 #include <connection_graph.h>
50 #include <lib_pin.h>
51 #include <netlist.h>
52 #include <netlist_object.h>
53 #include <sch_bus_entry.h>
54 #include <sch_component.h>
55 #include <sch_junction.h>
56 #include <sch_line.h>
57 #include <sch_marker.h>
58 #include <sch_no_connect.h>
59 #include <sch_rtree.h>
60 #include <sch_sheet.h>
61 #include <sch_text.h>
62 #include <symbol_lib_table.h>
63 #include <tool/common_tools.h>
64 
65 #include <thread>
66 #include <algorithm>
67 #include <future>
68 #include <array>
69 
70 // TODO(JE) Debugging only
71 #include <profile.h>
72 
73 #define EESCHEMA_FILE_STAMP "EESchema"
74 #define ZOOM_FACTOR( x ) ( x * IU_PER_MILS )
75 
76 
77 /* Default zoom values. Limited to these values to keep a decent size
78  * to menus
79  */
80 static double SchematicZoomList[] =
81 {
82  ZOOM_FACTOR( 0.5 ),
83  ZOOM_FACTOR( 0.7 ),
84  ZOOM_FACTOR( 1.0 ),
85  ZOOM_FACTOR( 1.5 ),
86  ZOOM_FACTOR( 2.0 ),
87  ZOOM_FACTOR( 3.0 ),
88  ZOOM_FACTOR( 4.0 ),
89  ZOOM_FACTOR( 6.0 ),
90  ZOOM_FACTOR( 8.0 ),
91  ZOOM_FACTOR( 11.0 ),
92  ZOOM_FACTOR( 13.0 ),
93  ZOOM_FACTOR( 16.0 ),
94  ZOOM_FACTOR( 20.0 ),
95  ZOOM_FACTOR( 26.0 ),
96  ZOOM_FACTOR( 32.0 ),
97  ZOOM_FACTOR( 48.0 ),
98  ZOOM_FACTOR( 64.0 ),
99  ZOOM_FACTOR( 80.0 ),
100  ZOOM_FACTOR( 128.0 )
101 };
102 
103 
104 /* Default grid sizes for the schematic editor.
105  * Do NOT add others values (mainly grid values in mm), because they
106  * can break the schematic: Because wires and pins are considered as
107  * connected when the are to the same coordinate we cannot mix
108  * coordinates in mils (internal units) and mm (that cannot exactly
109  * converted in mils in many cases). In fact schematic must only use
110  * 50 and 25 mils to place labels, wires and components others values
111  * are useful only for graphic items (mainly in library editor) so use
112  * integer values in mils only. The 100 mil grid is added to help
113  * conform to the KiCad Library Convention. Which states: "Using a
114  * 100mil grid, pin ends and origin must lie on grid nodes IEC-60617"
115 */
117  { ID_POPUP_GRID_LEVEL_100, wxRealPoint( Mils2iu( 100 ), Mils2iu( 100 ) ) },
118  { ID_POPUP_GRID_LEVEL_50, wxRealPoint( Mils2iu( 50 ), Mils2iu( 50 ) ) },
119  { ID_POPUP_GRID_LEVEL_25, wxRealPoint( Mils2iu( 25 ), Mils2iu( 25 ) ) },
120  { ID_POPUP_GRID_LEVEL_10, wxRealPoint( Mils2iu( 10 ), Mils2iu( 10 ) ) },
121  { ID_POPUP_GRID_LEVEL_5, wxRealPoint( Mils2iu( 5 ), Mils2iu( 5 ) ) },
122  { ID_POPUP_GRID_LEVEL_2, wxRealPoint( Mils2iu( 2 ), Mils2iu( 2 ) ) },
123  { ID_POPUP_GRID_LEVEL_1, wxRealPoint( Mils2iu( 1 ), Mils2iu( 1 ) ) },
124 };
125 
126 
129  KIWAY_HOLDER( aKiway, KIWAY_HOLDER::HOLDER_TYPE::SCREEN ),
130  m_paper( wxT( "A4" ) )
131 {
133 
134  SetZoom( 32 );
135 
136  for( unsigned zoom : SchematicZoomList )
137  m_ZoomList.push_back( zoom );
138 
139  for( GRID_TYPE grid : SchematicGridList )
140  AddGrid( grid );
141 
142  // Set the default grid size, now that the grid list is populated
143  SetGrid( wxRealPoint( Mils2iu( 50 ), Mils2iu( 50 ) ) );
144 
145  m_refCount = 0;
146 
147  // Suitable for schematic only. For libedit and viewlib, must be set to true
148  m_Center = false;
149 
150  InitDataPoints( m_paper.GetSizeIU() );
151 }
152 
153 
155 {
157  FreeDrawList();
158 }
159 
160 
162 {
163  m_refCount++;
164 }
165 
166 
168 {
169  wxCHECK_RET( m_refCount != 0,
170  wxT( "Screen reference count already zero. Bad programmer!" ) );
171  m_refCount--;
172 }
173 
174 
176 {
177  m_rtree.insert( aItem );
179 }
180 
181 
183 {
184  wxCHECK_RET( aScreen, "Invalid screen object." );
185 
186  // No need to descend the hierarchy. Once the top level screen is copied, all of it's
187  // children are copied as well.
188  for( auto aItem : aScreen->m_rtree )
189  m_rtree.insert( aItem );
190 
192  aScreen->Clear( false );
193 }
194 
195 
196 void SCH_SCREEN::Clear( bool aFree )
197 {
198  if( aFree )
199  FreeDrawList();
200  else
201  m_rtree.clear();
202 
203  // Clear the project settings
205 
206  m_titles.Clear();
207 }
208 
209 
211 {
212  // We don't know which order we will encounter dependent items (e.g. pins or fields), so
213  // we store the items to be deleted until we've fully cleared the tree before deleting
214  std::vector<SCH_ITEM*> delete_list;
215 
216  std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
217  []( SCH_ITEM* aItem ) {
218  return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
219  } );
220 
221  m_rtree.clear();
222 
223  for( auto item : delete_list )
224  delete item;
225 }
226 
227 
229 {
230  Remove( aItem );
231  Append( aItem );
232 }
233 
234 
236 {
237  m_rtree.remove( aItem );
238 }
239 
240 
242 {
243  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
244 
245  SetModify();
246  Remove( aItem );
247 
248  if( aItem->Type() == SCH_SHEET_PIN_T )
249  {
250  // This structure is attached to a sheet, get the parent sheet object.
251  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
252  SCH_SHEET* sheet = sheetPin->GetParent();
253  wxCHECK_RET( sheet, wxT( "Sheet label parent not properly set, bad programmer!" ) );
254  sheet->RemovePin( sheetPin );
255  return;
256  }
257  else
258  {
259  delete aItem;
260  }
261 }
262 
263 
265 {
266  return m_rtree.contains( aItem, true );
267 }
268 
269 
270 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType )
271 {
272  EDA_RECT bbox;
273  bbox.SetOrigin( aPosition );
274  bbox.Inflate( aAccuracy );
275 
276  for( auto item : Items().Overlapping( aType, bbox ) )
277  {
278  if( item->HitTest( aPosition, aAccuracy ) )
279  return item;
280  }
281 
282  return nullptr;
283 }
284 
285 
286 std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
287 {
288  std::set<SCH_ITEM*> retval;
289  std::stack<SCH_LINE*> to_search;
290 
291  wxCHECK_MSG( ( aSegment ) && ( aSegment->Type() == SCH_LINE_T ), retval,
292  wxT( "Invalid object pointer." ) );
293 
294  to_search.push( aSegment );
295 
296  while( !to_search.empty() )
297  {
298  auto test_item = to_search.top();
299  to_search.pop();
300 
301  for( auto item : Items().Overlapping( SCH_JUNCTION_T, test_item->GetBoundingBox() ) )
302  {
303  if( test_item->IsEndPoint( item->GetPosition() ) )
304  retval.insert( item );
305  }
306 
307  for( auto item : Items().Overlapping( SCH_LINE_T, test_item->GetBoundingBox() ) )
308  {
309  // Skip connecting lines on different layers (e.g. busses)
310  if( test_item->GetLayer() != item->GetLayer() )
311  continue;
312 
313  auto line = static_cast<SCH_LINE*>( item );
314 
315  if( ( test_item->IsEndPoint( line->GetStartPoint() )
316  && !GetPin( line->GetStartPoint(), NULL, true ) )
317  || ( test_item->IsEndPoint( line->GetEndPoint() )
318  && !GetPin( line->GetEndPoint(), nullptr, true ) ) )
319  {
320  auto result = retval.insert( line );
321 
322  if( result.second )
323  to_search.push( line );
324  }
325  }
326  }
327 
328  return retval;
329 }
330 
331 
332 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew )
333 {
334  enum { WIRES, BUSSES } layers;
335 
336  bool has_nonparallel[ sizeof( layers ) ] = { false };
337  int end_count[ sizeof( layers ) ] = { 0 };
338  int pin_count = 0;
339 
340  std::vector<SCH_LINE*> lines[ sizeof( layers ) ];
341 
342  for( auto item : Items().Overlapping( aPosition ) )
343  {
344  if( item->GetEditFlags() & STRUCT_DELETED )
345  continue;
346 
347  if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
348  return false;
349 
350  if( ( item->Type() == SCH_LINE_T ) && ( item->HitTest( aPosition, 0 ) ) )
351  {
352  if( item->GetLayer() == LAYER_WIRE )
353  lines[WIRES].push_back( (SCH_LINE*) item );
354  else if( item->GetLayer() == LAYER_BUS )
355  lines[BUSSES].push_back( (SCH_LINE*) item );
356  }
357 
358  if( ( item->Type() == SCH_COMPONENT_T ) && ( item->IsConnected( aPosition ) ) )
359  pin_count++;
360  }
361 
362  for( int i : { WIRES, BUSSES } )
363  {
364  bool removed_overlapping = false;
365  bool mid_point = false;
366 
367  for( auto line = lines[i].begin(); line < lines[i].end(); line++ )
368  {
369  if( !(*line)->IsEndPoint( aPosition ) )
370  mid_point = true;
371  else
372  end_count[i]++;
373 
374  for( auto second_line = lines[i].end() - 1; second_line > line; second_line-- )
375  {
376  if( !(*line)->IsParallel( *second_line ) )
377  has_nonparallel[i] = true;
378  else if( !removed_overlapping
379  && (*line)->IsSameQuadrant( *second_line, aPosition ) )
380  {
381  removed_overlapping = true;
382  }
383  }
384  }
385 
389  if( mid_point )
390  end_count[i] += 2;
391 
394  if( removed_overlapping )
395  end_count[i]--;
396  }
397 
398  // If there are three or more endpoints
399  if( pin_count && pin_count + end_count[WIRES] > 2 )
400  return true;
401 
402  // If there is at least one segment that ends on a non-parallel line or
403  // junction of two other lines
404  if( has_nonparallel[WIRES] && end_count[WIRES] > 2 )
405  return true;
406 
407  // Check for bus - bus junction requirements
408  if( has_nonparallel[BUSSES] && end_count[BUSSES] > 2 )
409  return true;
410 
411  return false;
412 }
413 
414 
415 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
416 {
417  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
418  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
419 
420  SCH_SHEET_PIN* label;
421  SCH_TEXT* text;
422  SCH_CONNECTION conn;
423 
424  switch( aLayer )
425  {
426  case LAYER_BUS:
427 
428  if( GetBus( aPosition ) )
429  return true;
430 
431  label = GetSheetLabel( aPosition );
432 
433  if( label && conn.IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
434  return true;
435 
436  text = GetLabel( aPosition );
437 
438  if( text && conn.IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
439  && (text->Type() != SCH_LABEL_T) )
440  return true;
441 
442  break;
443 
444  case LAYER_NOTES:
445 
446  if( GetLine( aPosition ) )
447  return true;
448 
449  break;
450 
451  case LAYER_WIRE:
452  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_WIRE_ENTRY_T) )
453  return true;
454 
455  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_BUS_ENTRY_T) )
456  return true;
457 
458  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_JUNCTION_T ) )
459  return true;
460 
461  if( GetPin( aPosition, NULL, true ) )
462  return true;
463 
464  if( GetWire( aPosition ) )
465  return true;
466 
467  text = GetLabel( aPosition );
468 
469  if( text && text->IsConnected( aPosition ) && !conn.IsBusLabel( text->GetText() ) )
470  return true;
471 
472  label = GetSheetLabel( aPosition );
473 
474  if( label && label->IsConnected( aPosition ) && !conn.IsBusLabel( label->GetText() ) )
475  return true;
476 
477  break;
478 
479  default:
480  break;
481  }
482 
483  return false;
484 }
485 
486 
487 void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
488 {
489  // Initialize or reinitialize the pointer to the LIB_PART for each component
490  // found in m_drawList, but only if needed (change in lib or schematic)
491  // therefore the calculation time is usually very low.
492  if( !IsEmpty() )
493  {
494  std::vector<SCH_COMPONENT*> cmps;
495  SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
496  int mod_hash = libs->GetModifyHash();
497 
498  for( auto aItem : Items().OfType( SCH_COMPONENT_T ) )
499  cmps.push_back( static_cast<SCH_COMPONENT*>( aItem ) );
500 
501  for( auto cmp : cmps )
502  Remove( cmp );
503 
504  // Must we resolve?
505  if( (m_modification_sync != mod_hash) || aForce )
506  {
507  SCH_COMPONENT::ResolveAll( cmps, *libs, Prj().SchLibs()->GetCacheLibrary() );
508 
509  m_modification_sync = mod_hash; // note the last mod_hash
510  }
511  // Resolving will update the pin caches but we must ensure that this happens
512  // even if the libraries don't change.
513  else
514  {
515  for( auto cmp : cmps )
516  cmp->UpdatePins();
517  }
518 
519  // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
520  // item with the new bbox
521  for( auto cmp : cmps )
522  Append( cmp );
523  }
524 }
525 
526 
527 void SCH_SCREEN::Print( wxDC* aDC )
528 {
529  // Ensure links are up to date, even if a library was reloaded for some reason:
530  std::vector< SCH_ITEM* > junctions;
531  std::vector<SCH_ITEM*> bitmaps;
532  std::vector<SCH_ITEM*> other;
533 
534  // Ensure links are up to date, even if a library was reloaded for some reason:
536 
537  for( auto item : Items() )
538  {
539  if( item->IsMoving() || item->IsResized() )
540  continue;
541 
542  if( item->Type() == SCH_JUNCTION_T )
543  junctions.push_back( item );
544  else if( item->Type() == SCH_BITMAP_T )
545  bitmaps.push_back( item );
546  else
547  other.push_back( item );
548  }
549 
551  std::sort( other.begin(), other.end(), []( const SCH_ITEM* a, const SCH_ITEM* b ) {
552  if( a->Type() == b->Type() )
553  return a->GetLayer() > b->GetLayer();
554 
555  return a->Type() > b->Type();
556  } );
557 
558  for( auto item : bitmaps )
559  item->Print( aDC, wxPoint( 0, 0 ) );
560 
561  for( auto item : other )
562  item->Print( aDC, wxPoint( 0, 0 ) );
563 
564  for( auto item : junctions )
565  item->Print( aDC, wxPoint( 0, 0 ) );
566 }
567 
568 
569 void SCH_SCREEN::Plot( PLOTTER* aPlotter )
570 {
571  // Ensure links are up to date, even if a library was reloaded for some reason:
572  std::vector< SCH_ITEM* > junctions;
573  std::vector< SCH_ITEM* > bitmaps;
574  std::vector< SCH_ITEM* > other;
575 
576  // Ensure links are up to date, even if a library was reloaded for some reason:
578 
579  for( auto item : Items() )
580  {
581  if( item->IsMoving() || item->IsResized() )
582  continue;
583 
584  if( item->Type() == SCH_JUNCTION_T )
585  junctions.push_back( item );
586  else if( item->Type() == SCH_BITMAP_T )
587  bitmaps.push_back( item );
588  else
589  other.push_back( item );
590  }
591 
593  std::sort( other.begin(), other.end(), []( const SCH_ITEM* a, const SCH_ITEM* b ) {
594  if( a->Type() == b->Type() )
595  return a->GetLayer() > b->GetLayer();
596 
597  return a->Type() > b->Type();
598  } );
599 
600  // Bitmaps are drawn first to ensure they are in the background
601  // This is particularly important for the wxPostscriptDC (used in *nix printers) as
602  // the bitmap PS command clears the screen
603  for( auto item : bitmaps )
604  {
605  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
606  item->Plot( aPlotter );
607  }
608 
609  for( auto item : other )
610  {
611  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
612  item->Plot( aPlotter );
613  }
614 
615  for( auto item : junctions )
616  {
617  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
618  item->Plot( aPlotter );
619  }
620 }
621 
622 
624 {
625  if( aItemCount == 0 )
626  return;
627 
628  for( auto& command : aList.m_CommandsList )
629  {
630  command->ClearListAndDeleteItems();
631  delete command;
632  }
633 
634  aList.m_CommandsList.clear();
635 }
636 
637 
639 {
640  for( auto item : Items() )
641  item->ClearTempFlags();
642 }
643 
644 
646  const wxPoint& aPosition, SCH_COMPONENT** aComponent, bool aEndPointOnly )
647 {
648  SCH_COMPONENT* component = NULL;
649  LIB_PIN* pin = NULL;
650 
651  for( auto item : Items().Overlapping( SCH_COMPONENT_T, aPosition ) )
652  {
653  component = static_cast<SCH_COMPONENT*>( item );
654 
655  if( aEndPointOnly )
656  {
657  pin = NULL;
658 
659  if( !component->GetPartRef() )
660  continue;
661 
662  for( pin = component->GetPartRef()->GetNextPin(); pin;
663  pin = component->GetPartRef()->GetNextPin( pin ) )
664  {
665  // Skip items not used for this part.
666  if( component->GetUnit() && pin->GetUnit() &&
667  ( pin->GetUnit() != component->GetUnit() ) )
668  continue;
669 
670  if( component->GetConvert() && pin->GetConvert() &&
671  ( pin->GetConvert() != component->GetConvert() ) )
672  continue;
673 
674  if(component->GetPinPhysicalPosition( pin ) == aPosition )
675  break;
676  }
677  if( pin )
678  break;
679  }
680  else
681  {
682  pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
683 
684  if( pin )
685  break;
686  }
687  }
688 
689  if( pin && aComponent )
690  *aComponent = component;
691 
692  return pin;
693 }
694 
695 
696 SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName )
697 {
698  for( auto item : Items().OfType( SCH_SHEET_T ) )
699  {
700  auto sheet = static_cast<SCH_SHEET*>( item );
701 
702  if( aName.CmpNoCase( sheet->GetName() ) == 0 )
703  return sheet;
704  }
705 
706  return NULL;
707 }
708 
709 
711 {
712  SCH_SHEET_PIN* sheetPin = nullptr;
713 
714  for( auto item : Items().OfType( SCH_SHEET_T ) )
715  {
716  auto sheet = static_cast<SCH_SHEET*>( item );
717 
718  sheetPin = sheet->GetPin( aPosition );
719 
720  if( sheetPin )
721  break;
722  }
723 
724  return sheetPin;
725 }
726 
727 
728 size_t SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions )
729 {
730  size_t count = 0;
731 
732  for( auto item : Items() )
733  {
734  if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
735  count++;
736  }
737 
738  return count;
739 }
740 
741 
743 {
744 
745  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
746  {
747  auto component = static_cast<SCH_COMPONENT*>( item );
748 
749  component->ClearAnnotation( aSheetPath );
750 
751  // Clear the modified component flag set by component->ClearAnnotation
752  // because we do not use it here and we should not leave this flag set,
753  // when an editing is finished:
754  component->ClearFlags();
755  }
756 }
757 
758 
760 {
761  if( GetClientSheetPathsCount() <= 1 ) // No need for alternate reference
762  return;
763 
764  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
765  {
766  auto component = static_cast<SCH_COMPONENT*>( item );
767 
768  // Add (when not existing) all sheet path entries
769  for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ )
770  component->AddSheetPathReferenceEntryIfMissing( m_clientSheetPathList[ii] );
771  }
772 }
773 
774 
776 {
777  for( auto item : Items() )
778  {
779  if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
780  aItems.push_back( item );
781  }
782 }
783 
784 
786 {
787  std::vector< DANGLING_END_ITEM > endPoints;
788  bool hasStateChanged = false;
789 
790  for( auto item : Items() )
791  item->GetEndPoints( endPoints );
792 
793  for( auto item : Items() )
794  {
795  if( item->UpdateDanglingState( endPoints ) )
796  hasStateChanged = true;
797  }
798 
799  return hasStateChanged;
800 }
801 
802 
803 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
804  SCH_LINE_TEST_T aSearchType )
805 {
806  for( auto item : Items() )
807  {
808  if( item->Type() != SCH_LINE_T )
809  continue;
810 
811  if( item->GetLayer() != aLayer )
812  continue;
813 
814  if( !item->HitTest( aPosition, aAccuracy ) )
815  continue;
816 
817  switch( aSearchType )
818  {
819  case ENTIRE_LENGTH_T:
820  return (SCH_LINE*) item;
821 
823  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
824  return (SCH_LINE*) item;
825  break;
826 
827  case END_POINTS_ONLY_T:
828  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
829  return (SCH_LINE*) item;
830  }
831  }
832 
833  return NULL;
834 }
835 
836 
837 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
838 {
839  for( auto item : Items().Overlapping( aPosition, aAccuracy ) )
840  {
841  switch( item->Type() )
842  {
843  case SCH_LABEL_T:
844  case SCH_GLOBAL_LABEL_T:
845  case SCH_HIER_LABEL_T:
846  if( item->HitTest( aPosition, aAccuracy ) )
847  return (SCH_TEXT*) item;
848 
849  default:
850  ;
851  }
852  }
853 
854  return NULL;
855 }
856 
857 
858 bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
859  const wxString& aFootPrint, bool aSetVisible )
860 {
861  SCH_COMPONENT* component;
862  bool found = false;
863 
864  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
865  {
866  component = static_cast<SCH_COMPONENT*>( item );
867 
868  if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
869  {
870  // Found: Init Footprint Field
871 
872  /* Give a reasonable value to the field position and
873  * orientation, if the text is empty at position 0, because
874  * it is probably not yet initialized
875  */
876  SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
877  if( fpfield->GetText().IsEmpty()
878  && ( fpfield->GetTextPos() == component->GetPosition() ) )
879  {
880  fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
881  fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
882  fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
883 
884  if( fpfield->GetTextAngle() == 0.0 )
885  fpfield->Offset( wxPoint( 0, Mils2iu( 100 ) ) );
886  else
887  fpfield->Offset( wxPoint( Mils2iu( 100 ), 0 ) );
888  }
889 
890  fpfield->SetText( aFootPrint );
891  fpfield->SetVisible( aSetVisible );
892 
893  found = true;
894  }
895  }
896 
897  return found;
898 }
899 
900 
901 void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
902 {
903  m_aliases.insert( aAlias );
904 }
905 
906 
907 bool SCH_SCREEN::IsBusAlias( const wxString& aLabel )
908 {
909  SCH_SHEET_LIST aSheets( g_RootSheet );
910  for( unsigned i = 0; i < aSheets.size(); i++ )
911  {
912  for( const auto& alias : aSheets[i].LastScreen()->GetBusAliases() )
913  {
914  if( alias->GetName() == aLabel )
915  {
916  return true;
917  }
918  }
919  }
920 
921  return false;
922 }
923 
924 
925 std::shared_ptr<BUS_ALIAS> SCH_SCREEN::GetBusAlias( const wxString& aLabel )
926 {
927  SCH_SHEET_LIST aSheets( g_RootSheet );
928  for( unsigned i = 0; i < aSheets.size(); i++ )
929  {
930  for( auto alias : aSheets[i].LastScreen()->GetBusAliases() )
931  {
932  if( alias->GetName() == aLabel )
933  {
934  return alias;
935  }
936  }
937  }
938 
939  return NULL;
940 }
941 
942 
943 #if defined(DEBUG)
944 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
945 {
946  // for now, make it look like XML, expand on this later.
947  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
948  for( const auto item : Items() )
949  {
950  item->Show( nestLevel + 1, os );
951  }
952 
953  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
954 }
955 #endif
956 
957 
959 {
960  m_index = 0;
961  buildScreenList( ( !aSheet ) ? g_RootSheet : aSheet );
962 }
963 
964 
966 {
967 }
968 
969 
971 {
972  m_index = 0;
973 
974  if( m_screens.size() > 0 )
975  return m_screens[0];
976 
977  return NULL;
978 }
979 
980 
982 {
983  if( m_index < m_screens.size() )
984  m_index++;
985 
986  return GetScreen( m_index );
987 }
988 
989 
990 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
991 {
992  if( aIndex < m_screens.size() )
993  return m_screens[ aIndex ];
994 
995  return NULL;
996 }
997 
998 
1000 {
1001  if( aScreen == NULL )
1002  return;
1003 
1004  for( unsigned int i = 0; i < m_screens.size(); i++ )
1005  {
1006  if( m_screens[i] == aScreen )
1007  return;
1008  }
1009 
1010  m_screens.push_back( aScreen );
1011 }
1012 
1013 
1015 {
1016  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1017  {
1018  SCH_SCREEN* screen = aSheet->GetScreen();
1019 
1020  addScreenToList( screen );
1021 
1022  for( auto item : screen->Items().OfType( SCH_SHEET_T ) )
1023  buildScreenList( static_cast<SCH_SHEET*>( item ) );
1024  }
1025 }
1026 
1027 
1029 {
1030  for( size_t i = 0; i < m_screens.size(); i++ )
1032 }
1033 
1034 
1036 {
1037  // Clear the annotation for the components inside new sheetpaths
1038  // not already in aInitialSheetList
1039  SCH_SCREENS screensList( g_RootSheet ); // The list of screens, shared by sheet paths
1040  screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1041 
1042  // Search for new sheet paths, not existing in aInitialSheetPathList
1043  // and existing in sheetpathList
1044  SCH_SHEET_LIST sheetpathList( g_RootSheet );
1045 
1046  for( SCH_SHEET_PATH& sheetpath: sheetpathList )
1047  {
1048  bool path_exists = false;
1049 
1050  for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1051  {
1052  if( existing_sheetpath.Path() == sheetpath.Path() )
1053  {
1054  path_exists = true;
1055  break;
1056  }
1057  }
1058 
1059  if( !path_exists )
1060  {
1061  // A new sheet path is found: clear the annotation corresponding to this new path:
1062  SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1063 
1064  // Clear annotation and create the AR for this path, if not exists,
1065  // when the screen is shared by sheet paths.
1066  // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1067  // reference default value and takes the latest displayed value
1068  curr_screen->EnsureAlternateReferencesExist();
1069  curr_screen->ClearAnnotation( &sheetpath );
1070  }
1071  }
1072 }
1073 
1074 
1076 {
1077  EDA_ITEMS items;
1078  int count = 0;
1079 
1080  auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1081  {
1082  return a->GetTimeStamp() < b->GetTimeStamp();
1083  };
1084 
1085  std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1086 
1087  for( size_t i = 0; i < m_screens.size(); i++ )
1088  m_screens[i]->GetHierarchicalItems( items );
1089 
1090  if( items.size() < 2 )
1091  return 0;
1092 
1093  for( auto item : items )
1094  {
1095  int failed = 0;
1096 
1097  while( !unique_stamps.insert( item ).second )
1098  {
1099  failed = 1;
1100 
1101  // for a component, update its Time stamp and its paths
1102  // (m_PathsAndReferences field)
1103  if( item->Type() == SCH_COMPONENT_T )
1104  static_cast<SCH_COMPONENT*>( item )->SetTimeStamp( GetNewTimeStamp() );
1105 
1106  // for a sheet, update only its time stamp (annotation of its
1107  // components will be lost)
1108  // @todo: see how to change sheet paths for its cmp list (can
1109  // be possible in most cases)
1110  else
1111  item->SetTimeStamp( GetNewTimeStamp() );
1112  }
1113 
1114  count += failed;
1115  }
1116 
1117  return count;
1118 }
1119 
1120 
1122 {
1123  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1124  {
1125  std::vector<SCH_ITEM*> markers;
1126 
1127  for( auto item : screen->Items().OfType( SCH_MARKER_T ) )
1128  {
1129  if( static_cast<SCH_MARKER*>( item )->GetMarkerType() == aMarkerType )
1130  markers.push_back( item );
1131  }
1132 
1133  for( auto marker : markers )
1134  {
1135  screen->Remove( marker );
1136  delete marker;
1137  }
1138  }
1139 }
1140 
1141 
1143  enum MARKER_BASE::MARKER_SEVERITY aSeverity )
1144 {
1145  int count = 0;
1146 
1147  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1148  {
1149  for( auto item : screen->Items().OfType( SCH_MARKER_T ) )
1150  {
1151  auto marker = static_cast<SCH_MARKER*>( item );
1152 
1153  if( ( aMarkerType != MARKER_BASE::MARKER_UNSPEC ) &&
1154  ( marker->GetMarkerType() != aMarkerType ) )
1155  continue;
1156 
1157  if( aSeverity == MARKER_BASE::MARKER_SEVERITY_UNSPEC ||
1158  aSeverity == marker->GetErrorLevel() )
1159  count++;
1160  }
1161  }
1162 
1163  return count;
1164 }
1165 
1166 
1168 {
1169  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1170  screen->UpdateSymbolLinks( aForce );
1171 
1172  SCH_SHEET_LIST sheets( g_RootSheet );
1173 
1174  // All of the library symbols have been replaced with copies so the connection graph
1175  // pointer are stale.
1176  if( g_ConnectionGraph )
1177  g_ConnectionGraph->Recalculate( sheets, true );
1178 }
1179 
1180 
1182 {
1183  std::vector<SCH_SCREEN*> screens;
1184  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1185  screens.push_back( screen );
1186 
1187  size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
1188  screens.size() );
1189 
1190  std::atomic<size_t> nextScreen( 0 );
1191  std::vector<std::future<size_t>> returns( parallelThreadCount );
1192 
1193  auto update_lambda = [&screens, &nextScreen]() -> size_t
1194  {
1195  for( auto i = nextScreen++; i < screens.size(); i = nextScreen++ )
1196  screens[i]->TestDanglingEnds();
1197 
1198  return 1;
1199  };
1200 
1201  if( parallelThreadCount == 1 )
1202  update_lambda();
1203  else
1204  {
1205  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1206  returns[ii] = std::async( std::launch::async, update_lambda );
1207 
1208  // Finalize the threads
1209  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1210  returns[ii].wait();
1211  }
1212 }
1213 
1214 
1216 {
1217  SCH_SCREEN* screen;
1218  unsigned cnt = 0;
1219 
1220  for( screen = GetFirst(); screen; screen = GetNext() )
1221  {
1222  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1223  {
1224  cnt++;
1225  auto symbol = static_cast<SCH_COMPONENT*>( item );
1226 
1227  if( !symbol->GetLibId().GetLibNickname().empty() )
1228  return false;
1229  }
1230  }
1231 
1232  return cnt != 0;
1233 }
1234 
1235 
1236 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1237 {
1238  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1239  {
1240  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1241  {
1242  auto symbol = static_cast<SCH_COMPONENT*>( item );
1243  auto& nickname = symbol->GetLibId().GetLibNickname();
1244 
1245  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1246  aLibNicknames.Add( nickname );
1247  }
1248  }
1249 
1250  return aLibNicknames.GetCount();
1251 }
1252 
1253 
1254 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1255 {
1256  SCH_SCREEN* screen;
1257  int cnt = 0;
1258 
1259  for( screen = GetFirst(); screen; screen = GetNext() )
1260  {
1261  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1262  {
1263  auto symbol = static_cast<SCH_COMPONENT*>( item );
1264 
1265  if( symbol->GetLibId().GetLibNickname() != aFrom )
1266  continue;
1267 
1268  LIB_ID id = symbol->GetLibId();
1269  id.SetLibNickname( aTo );
1270  symbol->SetLibId( id );
1271  cnt++;
1272  }
1273  }
1274 
1275  return cnt;
1276 }
1277 
1278 
1279 bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
1280 {
1281  for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1282  {
1283  if( screen->GetFileName() == aSchematicFileName )
1284  return true;
1285  }
1286 
1287  return false;
1288 }
1289 
1290 
1291 bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
1292 {
1293  wxString lhsLower;
1294  wxString rhsLower;
1295  wxFileName lhs;
1296  wxFileName rhs = aSchematicFileName;
1297 
1298  wxCHECK( rhs.IsAbsolute(), false );
1299 
1300  for( const SCH_SCREEN* screen : m_screens )
1301  {
1302  lhs = screen->GetFileName();
1303 
1304  if( lhs.GetPath() != rhs.GetPath() )
1305  continue;
1306 
1307  lhsLower = lhs.GetFullName().Lower();
1308  rhsLower = rhs.GetFullName().Lower();
1309 
1310  if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
1311  return true;
1312  }
1313 
1314  return false;
1315 }
1316 
1317 
1319 {
1320  SCH_SHEET_LIST sheetList( g_RootSheet );
1321 
1322  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1323  curr_screen->GetClientSheetPaths().Clear();
1324 
1325  for( SCH_SHEET_PATH& sheetpath: sheetList )
1326  {
1327  SCH_SCREEN* used_screen = sheetpath.LastScreen();
1328 
1329  // SEarch for the used_screen in list and add this unique sheet path:
1330  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1331  {
1332  if( used_screen == curr_screen )
1333  {
1334  curr_screen->GetClientSheetPaths().Add( sheetpath.Path() );
1335  break;
1336  }
1337  }
1338  }
1339 }
void SetTextAngle(double aAngle)
Definition: eda_text.h:150
SCH_SHEET_LIST.
void insert(SCH_ITEM *aItem)
Function Insert() Inserts an item into the tree.
Definition: sch_rtree.h:62
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
KIWAY_HOLDER is a mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_holder.h:39
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:237
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_COMPONENT **aComponent=NULL, bool aEndPointOnly=false)
Test the screen for a component pin item at aPosition.
Definition: sch_screen.cpp:645
SCH_SCREEN * GetNext()
Definition: sch_screen.cpp:981
int m_ScreenNumber
Definition: base_screen.h:135
void DeleteAllMarkers(enum MARKER_BASE::TYPEMARKER aMarkerType)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
Definition: sch_sheet.h:158
bool IsJunctionNeeded(const wxPoint &aPosition, bool aNew=false)
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:332
static double SchematicZoomList[]
Definition: sch_screen.cpp:80
SCH_SHEET * GetSheet(const wxString &aName)
Returns a sheet object pointer that is named aName.
Definition: sch_screen.cpp:696
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false)
Updates the connection graph for the given list of sheets.
static bool IsBusLabel(const wxString &aLabel)
Test if aLabel has a bus notation.
int GetClientSheetPathsCount()
Definition: sch_screen.h:179
void AddGrid(const GRID_TYPE &aGrid)
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in m_drawL...
Definition: sch_screen.cpp:487
wxArrayString & GetClientSheetPaths()
Definition: sch_screen.h:181
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i....
bool IsEmpty()
Definition: sch_screen.h:137
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
EE_TYPE Overlapping(const EDA_RECT &aRect)
Definition: sch_rtree.h:224
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:231
void SetVisible(bool aVisible)
Definition: eda_text.h:169
int m_refCount
Number of sheets referencing this screen.
Definition: sch_screen.h:91
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
static std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel)
Returns a pointer to a bus alias object for the given label, or null if one doesn't exist.
Definition: sch_screen.cpp:925
double GetTextAngle() const
Definition: eda_text.h:158
SCH_SCREEN(KIWAY *aKiway)
Constructor.
Definition: sch_screen.cpp:127
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
void Clear()
Definition: title_block.h:116
void Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:235
LIB_ITEM * GetDrawItem(const wxPoint &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the component library item at aPosition that is part of this component.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
Definition: sch_screen.cpp:759
#define ZOOM_FACTOR(x)
Definition: sch_screen.cpp:74
SCH_SCREENS(SCH_SHEET *aSheet=NULL)
Definition: sch_screen.cpp:958
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
int m_modification_sync
inequality with PART_LIBS::GetModificationHash() will trigger ResolveAll().
Definition: sch_screen.h:112
CONNECTION_GRAPH * g_ConnectionGraph
This also wants to live in the eventual SCHEMATIC object.
SCH_SCREEN * GetScreen()
Definition: sch_sheet.h:278
Field Name Module PCB, i.e. "16DIP300".
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:196
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
bool contains(SCH_ITEM *aItem, bool aRobust=false)
Determine if a given item exists in the tree.
Definition: sch_rtree.h:122
static GRID_TYPE SchematicGridList[]
Definition: sch_screen.cpp:116
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:65
SCH_LINE * GetLine(const wxPoint &aPosition, int aAccuracy=0, int aLayer=LAYER_NOTES, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Return a line item located at aPosition.
Definition: sch_screen.cpp:803
unsigned int m_index
Definition: sch_screen.h:502
UNDO_REDO_CONTAINER is a holder to handle alist of undo (or redo) command.
timestamp_t GetNewTimeStamp()
Definition: common.cpp:215
int GetUnit() const
Definition: lib_item.h:300
#define VALUE
int GetUnit() const
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:189
TITLE_BLOCK m_titles
Definition: sch_screen.h:105
static void ResolveAll(std::vector< SCH_COMPONENT * > &aComponents, SYMBOL_LIB_TABLE &aLibTable, PART_LIB *aCacheLib=NULL)
bool remove(SCH_ITEM *aItem)
Function Remove() Removes an item from the tree.
Definition: sch_rtree.h:78
PAGE_INFO m_paper
The size of the paper to print or plot on.
Definition: sch_screen.h:103
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
void GetHierarchicalItems(EDA_ITEMS &aItems)
Add all schematic sheet and component objects in the screen to aItems.
Definition: sch_screen.cpp:775
#define NULL
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
bool m_Center
Center on screen.
Definition: base_screen.h:121
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:241
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:601
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
SCH_LINE_TEST_T
Definition: sch_screen.h:61
BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:74
iterator end()
Definition: sch_rtree.h:253
const wxSize & GetTextSize() const
Definition: eda_text.h:223
EE_RTREE m_rtree
Definition: sch_screen.h:110
virtual void ClearUndoRedoList()
Function ClearUndoRedoList clear undo and redo list, using ClearUndoORRedoList() picked items are del...
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
timestamp_t GetTimeStamp() const
Definition: base_struct.h:213
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:129
KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the s...
Definition: kiway.h:274
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
SCH_SHEET_PIN * GetSheetLabel(const wxPoint &aPosition)
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:710
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:75
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
SCH_LINE * GetWire(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Definition: sch_screen.h:420
virtual bool SetZoom(double iu_per_du)
Function SetZoom adjusts the current zoom factor.
Definition: base_screen.cpp:88
SCH_SHEET_PATH.
std::unique_ptr< LIB_PART > & GetPartRef()
int GetConvert() const
Definition: lib_item.h:303
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
size_t CountConnectedItems(const wxPoint &aPos, bool aTestJunctions)
Definition: sch_screen.cpp:728
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:210
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:206
void Plot(PLOTTER *aPlotter)
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:569
int GetMarkerCount(enum MARKER_BASE::TYPEMARKER aMarkerType, enum MARKER_BASE::MARKER_SEVERITY aSeverity)
Return the number of ERC markers of aMarkerType from all of the screens in the list.
YYCODETYPE lhs
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
Definition: sch_item.h:212
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:167
Base plotter engine class.
Definition: plotter.h:103
void addScreenToList(SCH_SCREEN *aScreen)
Definition: sch_screen.cpp:999
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer)
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:415
see class PGM_BASE
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in the ful...
void TestDanglingEnds()
SCH_TEXT * GetLabel(const wxPoint &aPosition, int aAccuracy=0)
Return a label item located at aPosition.
Definition: sch_screen.cpp:837
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Adds a bus alias definition (and transfers ownership of the pointer)
Definition: sch_screen.cpp:901
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:38
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:501
GRID_TYPE is for grid arrays.
Definition: base_screen.h:43
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:175
void ClearAnnotation()
Clear the annotation for all components in the hierarchy.
iterator begin()
Definition: sch_rtree.h:248
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:785
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:116
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
wxPoint GetPosition() const override
Function GetPosition.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
The common library.
int m_NumberOfScreens
Definition: base_screen.h:136
const wxPoint & GetTextPos() const
Definition: eda_text.h:232
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:742
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2950
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T)
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:270
static bool IsBusAlias(const wxString &aLabel)
Returns true if the given string is a valid bus alias in a loaded screen.
Definition: sch_screen.cpp:907
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
int GetConvert() const
void Print(wxDC *aDC)
Print all the items in the screen to aDC.
Definition: sch_screen.cpp:527
SCH_SCREEN * GetFirst()
Definition: sch_screen.cpp:970
SCH_SCREEN * GetScreen(unsigned int aIndex) const
Definition: sch_screen.cpp:990
SCH_SHEET * g_RootSheet
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:638
void Update(SCH_ITEM *aItem)
Updates aItem's bounding box in the tree.
Definition: sch_screen.cpp:228
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:623
Definition for part library class.
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the components inside new sheetpaths when a complex hierarchy is modified an...
void SetModify()
Definition: base_screen.h:224
int SetGrid(const wxRealPoint &size)
set the current grid size m_Grid.
Definition of the NETLIST_OBJECT class.
bool CheckIfOnDrawList(SCH_ITEM *st)
Definition: sch_screen.cpp:264
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nickames into aLibNicknames.
SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:136
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
void clear()
Function RemoveAll() Removes all items from the RTree.
Definition: sch_rtree.h:108
bool IsConnected(const wxPoint &aPoint) const
Function IsConnected tests the item to see if it is connected to aPoint.
Definition: sch_item.cpp:119
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:498
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
std::vector< double > m_ZoomList
standard zoom (i.e. scale) coefficients.
Definition: base_screen.h:138
wxArrayString m_clientSheetPathList
the list of scheet paths sharing this screen used in some annotation calculations to update alternate...
Definition: sch_screen.h:100
void IncRefCount()
Definition: sch_screen.cpp:161
KICAD_T Type() const
Function Type()
Definition: base_struct.h:207
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_screen.h:147
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
bool SetComponentFootprint(SCH_SHEET_PATH *aSheetPath, const wxString &aReference, const wxString &aFootPrint, bool aSetVisible)
Search this screen for a symbol with aReference and set the footprint field to aFootPrint if found.
Definition: sch_screen.cpp:858
std::set< SCH_ITEM * > MarkConnections(SCH_LINE *aSegment)
Return all wires and junctions connected to aSegment which are not connected any component pin.
Definition: sch_screen.cpp:286
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Definition: sch_screen.h:426