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-2017 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 <fctsys.h>
33 #include <gr_basic.h>
34 #include <common.h>
35 #include <kicad_string.h>
36 #include <eeschema_id.h>
37 #include <pgm_base.h>
38 #include <kiway.h>
39 #include <sch_draw_panel.h>
40 #include <sch_item.h>
41 #include <draw_graphic_text.h>
42 #include <sch_edit_frame.h>
43 #include <plotter.h>
44 
45 #include <netlist.h>
46 #include <netlist_object.h>
47 #include <class_library.h>
48 #include <sch_junction.h>
49 #include <sch_bus_entry.h>
50 #include <sch_line.h>
51 #include <sch_marker.h>
52 #include <sch_no_connect.h>
53 #include <sch_sheet.h>
54 #include <sch_component.h>
55 #include <sch_text.h>
56 #include <lib_pin.h>
57 #include <symbol_lib_table.h>
58 #include <tool/common_tools.h>
59 
60 #include <thread>
61 #include <algorithm>
62 #include <future>
63 #include <array>
64 
65 // TODO(JE) Debugging only
66 #include <profile.h>
67 
68 #include <boost/foreach.hpp>
69 
70 #define EESCHEMA_FILE_STAMP "EESchema"
71 
72 /* Default zoom values. Limited to these values to keep a decent size
73  * to menus
74  */
75 static double SchematicZoomList[] =
76 {
77  0.5, 0.7, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 11.0,
78  13.0, 16.0, 20.0, 26.0, 32.0, 48.0, 64.0, 80.0, 128.0
79 };
80 
81 /* Default grid sizes for the schematic editor.
82  * Do NOT add others values (mainly grid values in mm), because they
83  * can break the schematic: Because wires and pins are considered as
84  * connected when the are to the same coordinate we cannot mix
85  * coordinates in mils (internal units) and mm (that cannot exactly
86  * converted in mils in many cases). In fact schematic must only use
87  * 50 and 25 mils to place labels, wires and components others values
88  * are useful only for graphic items (mainly in library editor) so use
89  * integer values in mils only. The 100 mil grid is added to help
90  * conform to the KiCad Library Convention. Which states: "Using a
91  * 100mil grid, pin ends and origin must lie on grid nodes IEC-60617"
92 */
94  { ID_POPUP_GRID_LEVEL_100, wxRealPoint( 100, 100 ) },
95  { ID_POPUP_GRID_LEVEL_50, wxRealPoint( 50, 50 ) },
96  { ID_POPUP_GRID_LEVEL_25, wxRealPoint( 25, 25 ) },
97  { ID_POPUP_GRID_LEVEL_10, wxRealPoint( 10, 10 ) },
98  { ID_POPUP_GRID_LEVEL_5, wxRealPoint( 5, 5 ) },
99  { ID_POPUP_GRID_LEVEL_2, wxRealPoint( 2, 2 ) },
100  { ID_POPUP_GRID_LEVEL_1, wxRealPoint( 1, 1 ) },
101 };
102 
103 
106  KIWAY_HOLDER( aKiway ),
107  m_paper( wxT( "A4" ) )
108 {
110 
111  SetZoom( 32 );
112 
113  for( unsigned i = 0; i < arrayDim( SchematicZoomList ); i++ )
114  m_ZoomList.push_back( SchematicZoomList[i] );
115 
116  for( unsigned i = 0; i < arrayDim( SchematicGridList ); i++ )
118 
119  // Set the default grid size, now that the grid list is populated
120  SetGrid( wxRealPoint( 50, 50 ) );
121 
122  m_refCount = 0;
123 
124  // Suitable for schematic only. For libedit and viewlib, must be set to true
125  m_Center = false;
126 
127  InitDataPoints( m_paper.GetSizeIU() );
128 }
129 
130 
132 {
134 
135  // Now delete items in draw list. We do that only if the list is not empty,
136  // because if the list was appended to another list (see SCH_SCREEN::Append( SCH_SCREEN* aScreen )
137  // it is empty but as no longer the ownership (m_drawList.meOwner == false) of items, and calling
138  // FreeDrawList() with m_drawList.meOwner == false will generate a debug alert in debug mode
139  if( GetDrawItems() )
140  FreeDrawList();
141 }
142 
143 
145 {
146  m_refCount++;
147 }
148 
149 
151 {
152  wxCHECK_RET( m_refCount != 0,
153  wxT( "Screen reference count already zero. Bad programmer!" ) );
154  m_refCount--;
155 }
156 
157 
159 {
160  wxCHECK_RET( aScreen, "Invalid screen object." );
161 
162  // No need to decend the hierarchy. Once the top level screen is copied, all of it's
163  // children are copied as well.
164  m_drawList.Append( aScreen->m_drawList );
165 
166  // This screen owns the objects now. This prevents the object from being delete when
167  // aSheet is deleted.
168  aScreen->m_drawList.SetOwnership( false );
169 }
170 
171 
173 {
174  FreeDrawList();
175 
176  // Clear the project settings
178 
179  m_titles.Clear();
180 }
181 
182 
184 {
186 }
187 
188 
190 {
191  m_drawList.Remove( aItem );
192 }
193 
194 
196 {
197  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
198 
199  SetModify();
200 
201  if( aItem->Type() == SCH_SHEET_PIN_T )
202  {
203  // This structure is attached to a sheet, get the parent sheet object.
204  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
205  SCH_SHEET* sheet = sheetPin->GetParent();
206  wxCHECK_RET( sheet, wxT( "Sheet label parent not properly set, bad programmer!" ) );
207  sheet->RemovePin( sheetPin );
208  return;
209  }
210  else
211  {
212  if( GetCurItem() == aItem )
213  SetCurItem( nullptr );
214 
215  m_drawList.Remove( aItem );
216  delete aItem;
217  }
218 }
219 
220 
222 {
223  SCH_ITEM* itemList = m_drawList.begin();
224 
225  while( itemList )
226  {
227  if( itemList == aItem )
228  return true;
229 
230  itemList = itemList->Next();
231  }
232 
233  return false;
234 }
235 
236 
237 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
238 {
239  KICAD_T types[] = { aType, EOT };
240 
241  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
242  {
243  switch( item->Type() )
244  {
245  case SCH_COMPONENT_T:
246  {
247  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
248 
249  for( int i = REFERENCE; i < component->GetFieldCount(); i++ )
250  {
251  SCH_FIELD* field = component->GetField( i );
252 
253  if( field->IsType( types ) && field->HitTest( aPosition, aAccuracy ) )
254  return field;
255  }
256 
257  break;
258  }
259  case SCH_SHEET_T:
260  {
261  SCH_SHEET* sheet = (SCH_SHEET*)item;
262 
263  SCH_SHEET_PIN* pin = sheet->GetPin( aPosition );
264 
265  if( pin && pin->IsType( types ) )
266  return pin;
267 
268  break;
269  }
270  default:
271  break;
272  }
273 
274  if( item->IsType( types ) && item->HitTest( aPosition, aAccuracy ) )
275  return item;
276  }
277 
278  return NULL;
279 }
280 
281 
283 {
284  SCH_ITEM* item;
285  SCH_ITEM* next_item;
286 
287  for( item = m_drawList.begin(); item; item = next_item )
288  {
289  next_item = item->Next();
290 
291  switch( item->Type() )
292  {
293  case SCH_JUNCTION_T:
294  case SCH_LINE_T:
295  Remove( item );
296  delete item;
297  break;
298 
299  default:
300  break;
301  }
302  }
303 
304  m_drawList.Append( aWireList );
305 }
306 
307 
309 {
310  wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T),
311  wxT( "Invalid object pointer." ) );
312 
313  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
314  {
315  if( item->GetFlags() & CANDIDATE )
316  continue;
317 
318  if( item->Type() == SCH_JUNCTION_T )
319  {
320  SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
321 
322  if( aSegment->IsEndPoint( junction->GetPosition() ) )
323  item->SetFlags( CANDIDATE );
324 
325  continue;
326  }
327 
328  if( item->Type() != SCH_LINE_T )
329  continue;
330 
331  SCH_LINE* segment = (SCH_LINE*) item;
332 
333  if( aSegment->IsEndPoint( segment->GetStartPoint() )
334  && !GetPin( segment->GetStartPoint(), NULL, true ) )
335  {
336  item->SetFlags( CANDIDATE );
337  MarkConnections( segment );
338  }
339 
340  if( aSegment->IsEndPoint( segment->GetEndPoint() )
341  && !GetPin( segment->GetEndPoint(), NULL, true ) )
342  {
343  item->SetFlags( CANDIDATE );
344  MarkConnections( segment );
345  }
346  }
347 }
348 
349 
350 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew )
351 {
352  bool has_nonparallel[2] = { false };
353  int end_count[2] = { 0 };
354  int pin_count = 0;
355 
356  std::vector<SCH_LINE*> lines[2];
357 
358  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
359  {
360  if( item->GetEditFlags() & STRUCT_DELETED )
361  continue;
362 
363  if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
364  return false;
365 
366  if( ( item->Type() == SCH_LINE_T )
367  && ( item->HitTest( aPosition, 0 ) ) )
368  {
369  if( item->GetLayer() == LAYER_WIRE )
370  lines[0].push_back( (SCH_LINE*) item );
371  else if( item->GetLayer() == LAYER_BUS )
372  lines[1].push_back( (SCH_LINE*) item );
373  }
374 
375  if( ( item->Type() == SCH_COMPONENT_T )
376  && ( item->IsConnected( aPosition ) ) )
377  pin_count++;
378  }
379 
380  for( int i = 0; i < 2; i++ )
381  {
382  bool removed_overlapping = false;
383  end_count[i] = lines[i].size();
384 
385  for( auto line = lines[i].begin(); line < lines[i].end(); line++ )
386  {
387  // Consider ending on a line to be equivalent to two endpoints because
388  // we will want to split the line if anything else connects
389  if( !(*line)->IsEndPoint( aPosition ) )
390  end_count[i]++;
391 
392  for( auto second_line = lines[i].end() - 1; second_line > line; second_line-- )
393  {
394  if( !(*line)->IsParallel( *second_line ) )
395  has_nonparallel[i] = true;
396  else if( !removed_overlapping
397  && (*line)->IsSameQuadrant( *second_line, aPosition ) )
398  {
404  removed_overlapping = true;
405  end_count[i]--;
406  }
407  }
408  }
409  }
410 
411  //
412 
413  // If there are three or more endpoints
414  if( pin_count + end_count[0] > 2 )
415  return true;
416 
417  // If there is at least one segment that ends on a non-parallel line or
418  // junction of two other lines
419  if( has_nonparallel[0] && end_count[0] > 2 )
420  return true;
421 
422  // Check for bus - bus junction requirements
423  if( has_nonparallel[1] && end_count[1] > 2 )
424  return true;
425 
426  return false;
427 }
428 
429 
430 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
431 {
432  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
433  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
434 
435  SCH_SHEET_PIN* label;
436  SCH_TEXT* text;
437  SCH_CONNECTION conn;
438 
439  switch( aLayer )
440  {
441  case LAYER_BUS:
442 
443  if( GetBus( aPosition ) )
444  return true;
445 
446  label = GetSheetLabel( aPosition );
447 
448  if( label && conn.IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
449  return true;
450 
451  text = GetLabel( aPosition );
452 
453  if( text && conn.IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
454  && (text->Type() != SCH_LABEL_T) )
455  return true;
456 
457  break;
458 
459  case LAYER_NOTES:
460 
461  if( GetLine( aPosition ) )
462  return true;
463 
464  break;
465 
466  case LAYER_WIRE:
468  return true;
469 
470  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_BUS_ENTRY_T) )
471  return true;
472 
473  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_JUNCTION_T ) )
474  return true;
475 
476  if( GetPin( aPosition, NULL, true ) )
477  return true;
478 
479  if( GetWire( aPosition ) )
480  return true;
481 
482  text = GetLabel( aPosition );
483 
484  if( text && text->IsConnected( aPosition ) && !conn.IsBusLabel( text->GetText() ) )
485  return true;
486 
487  label = GetSheetLabel( aPosition );
488 
489  if( label && label->IsConnected( aPosition ) && !conn.IsBusLabel( label->GetText() ) )
490  return true;
491 
492  break;
493 
494  default:
495  break;
496  }
497 
498  return false;
499 }
500 
501 
502 void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
503 {
504  // Initialize or reinitialize the pointer to the LIB_PART for each component
505  // found in m_drawList, but only if needed (change in lib or schematic)
506  // therefore the calculation time is usually very low.
507  if( m_drawList.GetCount() )
508  {
509  SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
510  int mod_hash = libs->GetModifyHash();
512 
514 
515  // Must we resolve?
516  if( (m_modification_sync != mod_hash) || aForce )
517  {
518  SCH_COMPONENT::ResolveAll( c, *libs, Prj().SchLibs()->GetCacheLibrary() );
519 
520  m_modification_sync = mod_hash; // note the last mod_hash
521  }
522  // Resolving will update the pin caches but we must ensure that this happens
523  // even if the libraries don't change.
524  else
526  }
527 }
528 
529 
530 void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
531 {
532  /* note: SCH_SCREEN::Draw is useful only for schematic.
533  * library editor and library viewer do not use m_drawList, and therefore
534  * their SCH_SCREEN::Draw() draws nothing
535  */
536  std::vector< SCH_ITEM* > junctions;
537 
538  // Ensure links are up to date, even if a library was reloaded for some reason:
540 
541  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
542  {
543  if( item->IsMoving() || item->IsResized() )
544  continue;
545 
546  if( item->Type() == SCH_JUNCTION_T )
547  junctions.push_back( item );
548  else
549  // uncomment line below when there is a virtual EDA_ITEM::GetBoundingBox()
550  // if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
551  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ) );
552 
553  // TODO(JE) Remove debugging code
554 #ifdef DEBUG
555 
556  auto conn = item->Connection( *g_CurrentSheet );
557 
558  if( conn )
559  {
560  auto pos = item->GetBoundingBox().Centre();
561  int sz = Mils2iu( 15 );
562  auto label = conn->Name( true );
563 
564  auto text = SCH_TEXT( pos, label, SCH_TEXT_T );
565  text.SetTextSize( wxSize( sz, sz ) );
566  text.Draw( aCanvas, aDC, wxPoint( 10, 10 ) );
567  }
568 #endif
569  }
570 
571  for( auto item : junctions )
572  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ) );
573 }
574 
575 
576 void SCH_SCREEN::Plot( PLOTTER* aPlotter )
577 {
578  // Ensure links are up to date, even if a library was reloaded for some reason:
580 
581  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
582  {
583  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
584  item->Plot( aPlotter );
585  }
586 }
587 
588 
590 {
591  if( aItemCount == 0 )
592  return;
593 
594  for( auto& command : aList.m_CommandsList )
595  {
596  command->ClearListAndDeleteItems();
597  delete command;
598  }
599 
600  aList.m_CommandsList.clear();
601 }
602 
603 
605 {
606  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
607  item->ClearTempFlags();
608 }
609 
610 
611 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent,
612  bool aEndPointOnly ) const
613 {
614  SCH_ITEM* item;
615  SCH_COMPONENT* component = NULL;
616  LIB_PIN* pin = NULL;
617 
618  for( item = m_drawList.begin(); item; item = item->Next() )
619  {
620  if( item->Type() != SCH_COMPONENT_T )
621  continue;
622 
623  component = (SCH_COMPONENT*) item;
624 
625  if( aEndPointOnly )
626  {
627  pin = NULL;
628 
629  auto part = component->GetPartRef().lock();
630 
631  if( !part )
632  continue;
633 
634  for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
635  {
636  // Skip items not used for this part.
637  if( component->GetUnit() && pin->GetUnit() &&
638  ( pin->GetUnit() != component->GetUnit() ) )
639  continue;
640 
641  if( component->GetConvert() && pin->GetConvert() &&
642  ( pin->GetConvert() != component->GetConvert() ) )
643  continue;
644 
645  if(component->GetPinPhysicalPosition( pin ) == aPosition )
646  break;
647  }
648  if( pin )
649  break;
650  }
651  else
652  {
653  pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
654 
655  if( pin )
656  break;
657  }
658  }
659 
660  if( pin && aComponent )
661  *aComponent = component;
662 
663  return pin;
664 }
665 
666 
667 SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName )
668 {
669  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
670  {
671  if( item->Type() != SCH_SHEET_T )
672  continue;
673 
674  SCH_SHEET* sheet = (SCH_SHEET*) item;
675 
676  if( aName.CmpNoCase( sheet->GetName() ) == 0 )
677  return sheet;
678  }
679 
680  return NULL;
681 }
682 
683 
684 SCH_SHEET_PIN* SCH_SCREEN::GetSheetLabel( const wxPoint& aPosition )
685 {
686  SCH_SHEET_PIN* sheetPin = NULL;
687 
688  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
689  {
690  if( item->Type() != SCH_SHEET_T )
691  continue;
692 
693  SCH_SHEET* sheet = (SCH_SHEET*) item;
694  sheetPin = sheet->GetPin( aPosition );
695 
696  if( sheetPin )
697  break;
698  }
699 
700  return sheetPin;
701 }
702 
703 
704 int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
705 {
706  SCH_ITEM* item;
707  int count = 0;
708 
709  for( item = m_drawList.begin(); item; item = item->Next() )
710  {
711  if( item->Type() == SCH_JUNCTION_T && !aTestJunctions )
712  continue;
713 
714  if( item->IsConnected( aPos ) )
715  count++;
716  }
717 
718  return count;
719 }
720 
721 
723 {
724  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
725  {
726  if( item->Type() == SCH_COMPONENT_T )
727  {
728  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
729 
730  component->ClearAnnotation( aSheetPath );
731 
732  // Clear the modified component flag set by component->ClearAnnotation
733  // because we do not use it here and we should not leave this flag set,
734  // when an editing is finished:
735  component->ClearFlags();
736  }
737  }
738 }
739 
740 
742 {
743  if( GetClientSheetPathsCount() <= 1 ) // No need for alternate reference
744  return;
745 
746  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
747  {
748  if( item->Type() != SCH_COMPONENT_T )
749  continue;
750 
751  // Add (when not existing) all sheet path entries
752  for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ )
753  ((SCH_COMPONENT*)item)->AddSheetPathReferenceEntryIfMissing( m_clientSheetPathList[ii] );
754  }
755 }
756 
757 
759 {
760  SCH_ITEM* item = m_drawList.begin();
761 
762  while( item )
763  {
764  if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
765  aItems.push_back( item );
766 
767  item = item->Next();
768  }
769 }
770 
771 
773 {
774  SCH_ITEM* item;
775  std::vector< DANGLING_END_ITEM > endPoints;
776  bool hasStateChanged = false;
777 
778  for( item = m_drawList.begin(); item; item = item->Next() )
779  item->GetEndPoints( endPoints );
780 
781  for( item = m_drawList.begin(); item; item = item->Next() )
782  {
783  if( item->UpdateDanglingState( endPoints ) )
784  {
785  hasStateChanged = true;
786  }
787  }
788 
789  return hasStateChanged;
790 }
791 
792 
793 SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition )
794 {
796 
797  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
798  {
799  if( item->IsType( types ) && item->HitTest( aPosition ) )
800  return (SCH_LINE*) item;
801  }
802 
803  return nullptr;
804 }
805 
806 
807 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
808  SCH_LINE_TEST_T aSearchType )
809 {
810  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
811  {
812  if( item->Type() != SCH_LINE_T )
813  continue;
814 
815  if( item->GetLayer() != aLayer )
816  continue;
817 
818  if( !item->HitTest( aPosition, aAccuracy ) )
819  continue;
820 
821  switch( aSearchType )
822  {
823  case ENTIRE_LENGTH_T:
824  return (SCH_LINE*) item;
825 
827  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
828  return (SCH_LINE*) item;
829  break;
830 
831  case END_POINTS_ONLY_T:
832  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
833  return (SCH_LINE*) item;
834  }
835  }
836 
837  return NULL;
838 }
839 
840 
841 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
842 {
843  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
844  {
845  switch( item->Type() )
846  {
847  case SCH_LABEL_T:
848  case SCH_GLOBAL_LABEL_T:
849  case SCH_HIER_LABEL_T:
850  if( item->HitTest( aPosition, aAccuracy ) )
851  return (SCH_TEXT*) item;
852 
853  default:
854  ;
855  }
856  }
857 
858  return NULL;
859 }
860 
861 
862 bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
863  const wxString& aFootPrint, bool aSetVisible )
864 {
865  SCH_COMPONENT* component;
866  bool found = false;
867 
868  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
869  {
870  if( item->Type() != SCH_COMPONENT_T )
871  continue;
872 
873  component = (SCH_COMPONENT*) item;
874 
875  if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
876  {
877  // Found: Init Footprint Field
878 
879  /* Give a reasonable value to the field position and
880  * orientation, if the text is empty at position 0, because
881  * it is probably not yet initialized
882  */
883  SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
884  if( fpfield->GetText().IsEmpty()
885  && ( fpfield->GetTextPos() == component->GetPosition() ) )
886  {
887  fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
888  fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
889  fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
890 
891  if( fpfield->GetTextAngle() == 0.0 )
892  fpfield->Offset( wxPoint( 0, 100 ) );
893  else
894  fpfield->Offset( wxPoint( 100, 0 ) );
895  }
896 
897  fpfield->SetText( aFootPrint );
898  fpfield->SetVisible( aSetVisible );
899 
900  found = true;
901  }
902  }
903 
904  return found;
905 }
906 
907 
908 void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
909 {
910  m_aliases.insert( aAlias );
911 }
912 
913 
914 bool SCH_SCREEN::IsBusAlias( const wxString& aLabel )
915 {
916  SCH_SHEET_LIST aSheets( g_RootSheet );
917  for( unsigned i = 0; i < aSheets.size(); i++ )
918  {
919  for( auto alias : aSheets[i].LastScreen()->GetBusAliases() )
920  {
921  if( alias->GetName() == aLabel )
922  {
923  return true;
924  }
925  }
926  }
927 
928  return false;
929 }
930 
931 
932 std::shared_ptr<BUS_ALIAS> SCH_SCREEN::GetBusAlias( const wxString& aLabel )
933 {
934  SCH_SHEET_LIST aSheets( g_RootSheet );
935  for( unsigned i = 0; i < aSheets.size(); i++ )
936  {
937  for( auto alias : aSheets[i].LastScreen()->GetBusAliases() )
938  {
939  if( alias->GetName() == aLabel )
940  {
941  return alias;
942  }
943  }
944  }
945 
946  return NULL;
947 }
948 
949 
950 #if defined(DEBUG)
951 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
952 {
953  // for now, make it look like XML, expand on this later.
954  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
955 
956  for( EDA_ITEM* item = m_drawList.begin(); item; item = item->Next() )
957  {
958  item->Show( nestLevel+1, os );
959  }
960 
961  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
962 }
963 #endif
964 
965 
969 static bool SortByTimeStamp( const EDA_ITEM* item1, const EDA_ITEM* item2 )
970 {
971  int ii = item1->GetTimeStamp() - item2->GetTimeStamp();
972 
973  /* If the time stamps are the same, compare type in order to have component objects
974  * before sheet object. This is done because changing the sheet time stamp
975  * before the component time stamp could cause the current annotation to be lost.
976  */
977  if( ( ii == 0 && ( item1->Type() != item2->Type() ) ) && ( item1->Type() == SCH_SHEET_T ) )
978  ii = -1;
979 
980  return ii < 0;
981 }
982 
983 
985 {
986  m_index = 0;
987  buildScreenList( ( !aSheet ) ? g_RootSheet : aSheet );
988 }
989 
990 
992 {
993 }
994 
995 
997 {
998  m_index = 0;
999 
1000  if( m_screens.size() > 0 )
1001  return m_screens[0];
1002 
1003  return NULL;
1004 }
1005 
1006 
1008 {
1009  if( m_index < m_screens.size() )
1010  m_index++;
1011 
1012  return GetScreen( m_index );
1013 }
1014 
1015 
1016 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1017 {
1018  if( aIndex < m_screens.size() )
1019  return m_screens[ aIndex ];
1020 
1021  return NULL;
1022 }
1023 
1024 
1026 {
1027  if( aScreen == NULL )
1028  return;
1029 
1030  for( unsigned int i = 0; i < m_screens.size(); i++ )
1031  {
1032  if( m_screens[i] == aScreen )
1033  return;
1034  }
1035 
1036  m_screens.push_back( aScreen );
1037 }
1038 
1039 
1041 {
1042  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1043  {
1044  SCH_SCREEN* screen = aSheet->GetScreen();
1045 
1046  addScreenToList( screen );
1047 
1048  EDA_ITEM* strct = screen->GetDrawItems();
1049 
1050  while( strct )
1051  {
1052  if( strct->Type() == SCH_SHEET_T )
1053  {
1054  buildScreenList( ( SCH_SHEET* )strct );
1055  }
1056 
1057  strct = strct->Next();
1058  }
1059  }
1060 }
1061 
1062 
1064 {
1065  for( size_t i = 0; i < m_screens.size(); i++ )
1066  m_screens[i]->ClearAnnotation( NULL );
1067 }
1068 
1069 
1071 {
1072  // Clear the annotation for the components inside new sheetpaths
1073  // not already in aInitialSheetList
1074  SCH_SCREENS screensList( g_RootSheet ); // The list of screens, shared by sheet paths
1075  screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1076 
1077  // Search for new sheet paths, not existing in aInitialSheetPathList
1078  // and existing in sheetpathList
1079  SCH_SHEET_LIST sheetpathList( g_RootSheet );
1080 
1081  for( SCH_SHEET_PATH& sheetpath: sheetpathList )
1082  {
1083  bool path_exists = false;
1084 
1085  for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1086  {
1087  if( existing_sheetpath.Path() == sheetpath.Path() )
1088  {
1089  path_exists = true;
1090  break;
1091  }
1092  }
1093 
1094  if( !path_exists )
1095  {
1096  // A new sheet path is found: clear the annotation corresponding to this new path:
1097  SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1098 
1099  // Clear annotation and create the AR for this path, if not exists,
1100  // when the screen is shared by sheet paths.
1101  // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1102  // reference default value and takes the latest displayed value
1103  curr_screen->EnsureAlternateReferencesExist();
1104  curr_screen->ClearAnnotation( &sheetpath );
1105  }
1106  }
1107 }
1108 
1109 
1111 {
1112  EDA_ITEMS items;
1113  SCH_ITEM* item;
1114 
1115  for( size_t i = 0; i < m_screens.size(); i++ )
1116  m_screens[i]->GetHierarchicalItems( items );
1117 
1118  if( items.size() < 2 )
1119  return 0;
1120 
1121  sort( items.begin(), items.end(), SortByTimeStamp );
1122 
1123  int count = 0;
1124 
1125  for( size_t ii = 0; ii < items.size() - 1; ii++ )
1126  {
1127  item = (SCH_ITEM*)items[ii];
1128 
1129  SCH_ITEM* nextItem = (SCH_ITEM*)items[ii + 1];
1130 
1131  if( item->GetTimeStamp() == nextItem->GetTimeStamp() )
1132  {
1133  count++;
1134 
1135  // for a component, update its Time stamp and its paths
1136  // (m_PathsAndReferences field)
1137  if( item->Type() == SCH_COMPONENT_T )
1138  ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
1139 
1140  // for a sheet, update only its time stamp (annotation of its
1141  // components will be lost)
1142  // @todo: see how to change sheet paths for its cmp list (can
1143  // be possible in most cases)
1144  else
1145  item->SetTimeStamp( GetNewTimeStamp() );
1146  }
1147  }
1148 
1149  return count;
1150 }
1151 
1152 
1154 {
1155  SCH_ITEM* item;
1156  SCH_ITEM* nextItem;
1157  SCH_MARKER* marker;
1158  SCH_SCREEN* screen;
1159 
1160  for( screen = GetFirst(); screen; screen = GetNext() )
1161  {
1162  for( item = screen->GetDrawItems(); item; item = nextItem )
1163  {
1164  nextItem = item->Next();
1165 
1166  if( item->Type() != SCH_MARKER_T )
1167  continue;
1168 
1169  marker = (SCH_MARKER*) item;
1170 
1171  if( marker->GetMarkerType() != aMarkerType )
1172  continue;
1173 
1174  screen->DeleteItem( marker );
1175  }
1176  }
1177 }
1178 
1179 
1181  enum MARKER_BASE::MARKER_SEVERITY aSeverity )
1182 {
1183  int count = 0;
1184 
1185  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1186  {
1187  for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
1188  {
1189  if( item->Type() != SCH_MARKER_T )
1190  continue;
1191 
1192  SCH_MARKER* marker = (SCH_MARKER*) item;
1193 
1194  if( ( aMarkerType != MARKER_BASE::MARKER_UNSPEC ) &&
1195  ( marker->GetMarkerType() != aMarkerType ) )
1196  continue;
1197 
1198  if( aSeverity == MARKER_BASE::MARKER_SEVERITY_UNSPEC ||
1199  aSeverity == marker->GetErrorLevel() )
1200  count++;
1201  }
1202  }
1203 
1204  return count;
1205 }
1206 
1207 
1209 {
1210  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1211  screen->UpdateSymbolLinks( aForce );
1212 }
1213 
1214 
1216 {
1217  std::vector<SCH_SCREEN*> screens;
1218  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1219  screens.push_back( screen );
1220 
1221  size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
1222  screens.size() );
1223 
1224  std::atomic<size_t> nextScreen( 0 );
1225  std::vector<std::future<size_t>> returns( parallelThreadCount );
1226 
1227  auto update_lambda = [&screens, &nextScreen]() -> size_t
1228  {
1229  for( auto i = nextScreen++; i < screens.size(); i = nextScreen++ )
1230  screens[i]->TestDanglingEnds();
1231 
1232  return 1;
1233  };
1234 
1235  if( parallelThreadCount == 1 )
1236  update_lambda();
1237  else
1238  {
1239  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1240  returns[ii] = std::async( std::launch::async, update_lambda );
1241 
1242  // Finalize the threads
1243  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1244  returns[ii].wait();
1245  }
1246 
1247 }
1248 
1249 
1251 {
1252  SCH_COMPONENT* symbol;
1253  SCH_ITEM* item;
1254  SCH_ITEM* nextItem;
1255  SCH_SCREEN* screen;
1256  unsigned cnt = 0;
1257 
1258  for( screen = GetFirst(); screen; screen = GetNext() )
1259  {
1260  for( item = screen->GetDrawItems(); item; item = nextItem )
1261  {
1262  nextItem = item->Next();
1263 
1264  if( item->Type() != SCH_COMPONENT_T )
1265  continue;
1266 
1267  cnt += 1;
1268  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1269  wxASSERT( symbol );
1270 
1271  if( !symbol->GetLibId().GetLibNickname().empty() )
1272  return false;
1273  }
1274  }
1275 
1276  if( cnt == 0 )
1277  return false;
1278 
1279  return true;
1280 }
1281 
1282 
1283 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1284 {
1285  SCH_COMPONENT* symbol;
1286  SCH_ITEM* item;
1287  SCH_ITEM* nextItem;
1288  SCH_SCREEN* screen;
1289  wxString nickname;
1290 
1291  for( screen = GetFirst(); screen; screen = GetNext() )
1292  {
1293  for( item = screen->GetDrawItems(); item; item = nextItem )
1294  {
1295  nextItem = item->Next();
1296 
1297  if( item->Type() != SCH_COMPONENT_T )
1298  continue;
1299 
1300  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1301  wxASSERT( symbol );
1302 
1303  if( !symbol )
1304  continue;
1305 
1306  nickname = symbol->GetLibId().GetLibNickname();
1307 
1308  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1309  aLibNicknames.Add( nickname );;
1310  }
1311  }
1312 
1313  return aLibNicknames.GetCount();
1314 }
1315 
1316 
1317 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1318 {
1319  SCH_COMPONENT* symbol;
1320  SCH_ITEM* item;
1321  SCH_ITEM* nextItem;
1322  SCH_SCREEN* screen;
1323  int cnt = 0;
1324 
1325  for( screen = GetFirst(); screen; screen = GetNext() )
1326  {
1327  for( item = screen->GetDrawItems(); item; item = nextItem )
1328  {
1329  nextItem = item->Next();
1330 
1331  if( item->Type() != SCH_COMPONENT_T )
1332  continue;
1333 
1334  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1335  wxASSERT( symbol );
1336 
1337  if( symbol->GetLibId().GetLibNickname() != aFrom )
1338  continue;
1339 
1340  LIB_ID id = symbol->GetLibId();
1341  id.SetLibNickname( aTo );
1342  symbol->SetLibId( id );
1343  cnt++;
1344  }
1345  }
1346 
1347  return cnt;
1348 }
1349 
1350 
1352 {
1353  SCH_SHEET_LIST sheetList( g_RootSheet );
1354 
1355  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1356  curr_screen->GetClientSheetPaths().Clear();
1357 
1358  for( SCH_SHEET_PATH& sheetpath: sheetList )
1359  {
1360  SCH_SCREEN* used_screen = sheetpath.LastScreen();
1361 
1362  // SEarch for the used_screen in list and add this unique sheet path:
1363  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1364  {
1365  if( used_screen == curr_screen )
1366  {
1367  curr_screen->GetClientSheetPaths().Add( sheetpath.Path() );
1368  break;
1369  }
1370  }
1371  }
1372 }
void SetTextAngle(double aAngle)
Definition: eda_text.h:173
Class SCH_SHEET_LIST.
void Collect(EDA_ITEM *aItem, const KICAD_T aScanList[])
Function Collect scans a DLIST using this class's Inspector method, which does the collection.
static void UpdatePins(const EE_COLLECTOR &aComponents)
Update the pin cache for all components in aComponents.
Class SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
Class KIWAY_HOLDER is a mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_player.h:49
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:246
bool IsType(const KICAD_T aScanTypes[]) override
Function IsType Checks whether the item is one of the listed types.
Definition: sch_field.h:73
void SetCurItem(EDA_ITEM *aItem)
Function SetCurItem sets the currently selected object, m_CurrentItem.
Definition: base_screen.h:231
SCH_SCREEN * GetNext()
int m_ScreenNumber
Definition: base_screen.h:216
SCH_SHEET_PIN * GetPin(const wxPoint &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:371
PART_REF & GetPartRef()
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:153
T * Remove(T *aElement)
Function Remove removes aElement from the list, but does not delete it.
Definition: dlist.h:211
wxPoint GetStartPoint() const
Definition: sch_line.h:90
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:350
virtual void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList)
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points.
Definition: sch_item.h:274
SCH_ITEM * Next() const
Definition: sch_item.h:153
MARKER_SEVERITY GetErrorLevel() const
Definition: marker_base.h:175
static double SchematicZoomList[]
Definition: sch_screen.cpp:75
SCH_SHEET * GetSheet(const wxString &aName)
Returns a sheet object pointer that is named aName.
Definition: sch_screen.cpp:667
static bool IsBusLabel(const wxString &aLabel)
Test if aLabel has a bus notation.
const wxString GetText() const override
Function GetText returns the string associated with the text object.
Definition: sch_field.cpp:105
int GetClientSheetPathsCount()
Definition: sch_screen.h:146
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
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:502
wxArrayString & GetClientSheetPaths()
Definition: sch_screen.h:148
void SetText(const wxString &aText) override
Definition: sch_field.cpp:125
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i....
int CountConnectedItems(const wxPoint &aPos, bool aTestJunctions) const
Definition: sch_screen.cpp:704
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:240
void SetVisible(bool aVisible)
Definition: eda_text.h:192
int m_refCount
Number of sheets referencing this screen.
Definition: sch_screen.h:76
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:932
double GetTextAngle() const
Definition: eda_text.h:181
SCH_SCREEN(KIWAY *aKiway)
Constructor.
Definition: sch_screen.cpp:104
EDA_ITEM * GetCurItem() const
Definition: base_screen.h:233
virtual bool IsType(const KICAD_T aScanTypes[])
Function IsType Checks whether the item is one of the listed types.
Definition: base_struct.h:287
T * begin() const
Definition: dlist.h:218
void Clear()
Definition: title_block.h:127
virtual const wxString GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:147
void Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:189
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:231
static const KICAD_T ComponentsOnly[]
Definition: ee_collectors.h:44
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
Definition: sch_screen.cpp:741
SCH_SCREENS(SCH_SHEET *aSheet=NULL)
Definition: sch_screen.cpp:984
#define CANDIDATE
flag indicating that the structure is connected
Definition: base_struct.h:124
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:44
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:97
SCH_SCREEN * GetScreen()
Definition: sch_sheet.h:268
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
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
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_COMPONENT **aComponent=NULL, bool aEndPointOnly=false) const
Test the screen for a component pin item at aPosition.
Definition: sch_screen.cpp:611
EDA_ITEM * Next() const
Definition: base_struct.h:212
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
static GRID_TYPE SchematicGridList[]
Definition: sch_screen.cpp:93
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:72
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:807
unsigned int m_index
Definition: sch_screen.h:497
Class UNDO_REDO_CONTAINER is a holder to handle alist of undo (or redo) command.
virtual bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList)
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it's dangling state...
Definition: sch_item.h:289
timestamp_t GetNewTimeStamp()
Definition: common.cpp:217
int GetUnit() const
#define VALUE
void SetLibId(const LIB_ID &aName, PART_LIBS *aLibs=NULL)
int GetUnit() const
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:187
TITLE_BLOCK m_titles
Definition: sch_screen.h:90
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:259
PAGE_INFO m_paper
The size of the paper to print or plot on.
Definition: sch_screen.h:88
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:56
void GetHierarchicalItems(EDA_ITEMS &aItems)
Add all schematic sheet and component objects in the screen to aItems.
Definition: sch_screen.cpp:758
wxString GetName() const
Definition: sch_sheet.h:259
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_junction.h:95
bool m_Center
Center on screen.
Definition: base_screen.h:202
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:195
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:588
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
SCH_LINE_TEST_T
Definition: sch_screen.h:58
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
void MarkConnections(SCH_LINE *aSegment)
Add all wires and junctions connected to aSegment which are not connected any component pin to aItemL...
Definition: sch_screen.cpp:308
const wxSize & GetTextSize() const
Definition: eda_text.h:232
virtual void ClearUndoRedoList()
Function ClearUndoRedoList clear undo and redo list, using ClearUndoORRedoList() picked items are del...
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:237
void Clear()
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:172
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
timestamp_t GetTimeStamp() const
Definition: base_struct.h:210
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:123
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:258
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: sch_field.cpp:453
SCH_SHEET_PIN * GetSheetLabel(const wxPoint &aPosition)
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:684
bool IsEndPoint(const wxPoint &aPoint) const
Definition: sch_line.h:83
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:56
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:415
virtual bool SetZoom(double iu_per_du)
Function SetZoom adjusts the current zoom factor.
Class SCH_SHEET_PATH.
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
int GetConvert() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
int GetFieldCount() const
Return the number of fields in this symbol.
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:183
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:201
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:107
void Plot(PLOTTER *aPlotter)
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:576
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.
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
DLIST< SCH_ITEM > m_drawList
Object list for the screen.
Definition: sch_screen.h:95
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:150
Base plotter engine class.
Definition: plotter.h:97
void addScreenToList(SCH_SCREEN *aScreen)
void AddGrid(const GRID_TYPE &grid)
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer)
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:430
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:841
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Adds a bus alias definition (and transfers ownership of the pointer)
Definition: sch_screen.cpp:908
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:496
Class GRID_TYPE is for grid arrays.
Definition: base_screen.h:45
void Append(SCH_ITEM *aItem)
Definition: sch_screen.h:155
void ClearAnnotation()
Clear the annotation for all components in the hierarchy.
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:187
#define max(a, b)
Definition: auxiliary.h:86
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
Class EE_TYPE_COLLECTOR merely gathers up all SCH_ITEMs of a given set of KICAD_T type(s).
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:772
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:101
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
wxPoint GetPosition() const override
Function GetPosition.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:157
The common library.
SCH_LINE * GetWireOrBus(const wxPoint &aPosition)
Return a wire or bus item located at aPosition.
Definition: sch_screen.cpp:793
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:260
int m_NumberOfScreens
Definition: base_screen.h:217
const wxPoint & GetTextPos() const
Definition: eda_text.h:241
void SetOwnership(bool Iown)
Function SetOwnership controls whether the list owns the objects and is responsible for deleteing the...
Definition: dlist.h:119
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:722
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
void ReplaceWires(DLIST< SCH_ITEM > &aWireList)
Replace all of the wires, buses, and junctions in the screen with aWireList.
Definition: sch_screen.cpp:282
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:914
int GetConvert() const
SCH_SCREEN * GetFirst()
Definition: sch_screen.cpp:996
SCH_SCREEN * GetScreen(unsigned int aIndex) const
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:604
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:589
void Draw(EDA_DRAW_PANEL *aCanvas, wxDC *aDC)
Draw all the items in the screen to aCanvas.
Definition: sch_screen.cpp:530
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:324
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:221
const LIB_ID & GetLibId() const
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nickames into aLibNicknames.
static bool SortByTimeStamp(const EDA_ITEM *item1, const EDA_ITEM *item2)
Sort a list of schematic items by time stamp and type.
Definition: sch_screen.cpp:969
static void ResolveAll(const EE_COLLECTOR &aComponents, SYMBOL_LIB_TABLE &aLibTable, PART_LIB *aCacheLib=NULL)
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Definition: sch_item.h:114
Implementation of the label properties dialog.
bool IsConnected(const wxPoint &aPoint) const
Function IsConnected tests the item to see if it is connected to aPoint.
Definition: sch_item.cpp:118
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:493
std::vector< double > m_ZoomList
standard zoom (i.e. scale) coefficients.
Definition: base_screen.h:219
wxArrayString m_clientSheetPathList
the list of scheet paths sharing this screen used in some annotation calculations to update alternate...
Definition: sch_screen.h:85
void IncRefCount()
Definition: sch_screen.cpp:144
KICAD_T Type() const
Function Type()
Definition: base_struct.h:204
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:209
bool empty() const
Definition: utf8.h:108
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_screen.h:114
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:862
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Definition: sch_screen.h:421
SCH_ITEM * GetDrawItems() const
Definition: sch_screen.h:153
wxPoint GetEndPoint() const
Definition: sch_line.h:93