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