KiCad PCB EDA Suite
sch_screen.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
32 #include <common.h>
33 #include <eda_rect.h>
34 #include <fctsys.h>
35 #include <gr_text.h>
36 #include <id.h>
37 #include <kicad_string.h>
38 #include <kiway.h>
39 #include <pgm_base.h>
40 #include <plotter.h>
41 #include <project.h>
42 #include <reporter.h>
43 #include <sch_draw_panel.h>
44 #include <sch_edit_frame.h>
45 #include <sch_item.h>
46 
47 #include <class_library.h>
48 #include <class_libentry.h>
49 #include <connection_graph.h>
50 #include <lib_pin.h>
51 #include <netlist_object.h>
52 #include <sch_component.h>
53 #include <sch_junction.h>
54 #include <sch_line.h>
55 #include <sch_marker.h>
56 #include <sch_sheet.h>
57 #include <sch_text.h>
58 #include <schematic.h>
59 #include <symbol_lib_table.h>
60 #include <tool/common_tools.h>
61 
62 #include <thread>
63 #include <algorithm>
64 #include <future>
65 
66 // TODO(JE) Debugging only
67 #include <profile.h>
68 
69 
71  BASE_SCREEN( aParent, SCH_SCREEN_T ),
72  m_paper( wxT( "A4" ) )
73 {
75 
76  m_refCount = 0;
77 
78  // Suitable for schematic only. For libedit and viewlib, must be set to true
79  m_Center = false;
80 
81  InitDataPoints( m_paper.GetSizeIU() );
82 }
83 
84 
86 {
89  FreeDrawList();
90 }
91 
92 
94 {
95  wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr,
96  "SCH_SCREEN must have a SCHEMATIC parent!" );
97 
98  return static_cast<SCHEMATIC*>( GetParent() );
99 }
100 
101 
103 {
104  for( auto libSymbol : m_libSymbols )
105  delete libSymbol.second;
106 
107  m_libSymbols.clear();
108 }
109 
110 
112 {
113  m_refCount++;
114 }
115 
116 
118 {
119  wxCHECK_RET( m_refCount != 0,
120  wxT( "Screen reference count already zero. Bad programmer!" ) );
121  m_refCount--;
122 }
123 
124 
125 bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const
126 {
127  EE_RTREE::EE_TYPE sheets = const_cast<EE_RTREE&>( m_rtree ).OfType( aItemType );
128 
129  return sheets.begin() != sheets.end();
130 }
131 
132 
134 {
135  if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
136  {
137  // Ensure the item can reach the SCHEMATIC through this screen
138  aItem->SetParent( this );
139 
140  if( aItem->Type() == SCH_COMPONENT_T )
141  {
142  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( aItem );
143 
144  if( symbol->GetPartRef() )
145  {
146  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
147 
148  if( it == m_libSymbols.end() )
149  {
151  new LIB_PART( *symbol->GetPartRef() );
152  }
153  else
154  {
155  // The original library symbol may have changed since the last time
156  // it was added to the schematic. If it has changed, then a new name
157  // must be created for the library symbol list to prevent all of the
158  // other schematic symbols referencing that library symbol from changing.
159  LIB_PART* foundSymbol = it->second;
160 
161  if( *foundSymbol != *symbol->GetPartRef() )
162  {
163  int cnt = 1;
164  wxString newName;
165 
166  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
167 
168  while( m_libSymbols.find( newName ) != m_libSymbols.end() )
169  {
170  cnt += 1;
171  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
172  }
173 
174  symbol->SetSchSymbolLibraryName( newName );
175  m_libSymbols[newName] = new LIB_PART( *symbol->GetPartRef() );
176  }
177  }
178  }
179  }
180 
181  m_rtree.insert( aItem );
183  }
184 }
185 
186 
188 {
189  wxCHECK_RET( aScreen, "Invalid screen object." );
190 
191  // No need to descend the hierarchy. Once the top level screen is copied, all of it's
192  // children are copied as well.
193  for( auto aItem : aScreen->m_rtree )
194  Append( aItem );
195 
196  aScreen->Clear( false );
197 }
198 
199 
200 void SCH_SCREEN::Clear( bool aFree )
201 {
202  if( aFree )
203  {
204  FreeDrawList();
205  clearLibSymbols();
206  }
207  else
208  {
209  m_rtree.clear();
210  }
211 
212  // Clear the project settings
214 
215  m_titles.Clear();
216 }
217 
218 
220 {
221  // We don't know which order we will encounter dependent items (e.g. pins or fields), so
222  // we store the items to be deleted until we've fully cleared the tree before deleting
223  std::vector<SCH_ITEM*> delete_list;
224 
225  std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
226  []( SCH_ITEM* aItem )
227  {
228  return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
229  } );
230 
231  m_rtree.clear();
232 
233  for( auto item : delete_list )
234  delete item;
235 }
236 
237 
239 {
240  if( Remove( aItem ) )
241  Append( aItem );
242 }
243 
244 
246 {
247  bool retv = m_rtree.remove( aItem );
248 
249  // Check if the library symbol for the removed schematic symbol is still required.
250  if( retv && aItem->Type() == SCH_COMPONENT_T )
251  {
252  SCH_COMPONENT* removedSymbol = static_cast<SCH_COMPONENT*>( aItem );
253 
254  bool removeUnusedLibSymbol = true;
255 
256  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
257  {
258  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
259 
260  if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
261  {
262  removeUnusedLibSymbol = false;
263  break;
264  }
265  }
266 
267  if( removeUnusedLibSymbol )
268  {
269  auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
270 
271  if( it != m_libSymbols.end() )
272  {
273  delete it->second;
274  m_libSymbols.erase( it );
275  }
276  }
277  }
278 
279  return retv;
280 }
281 
282 
284 {
285  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
286 
287  SetModify();
288  Remove( aItem );
289 
290  if( aItem->Type() == SCH_SHEET_PIN_T )
291  {
292  // This structure is attached to a sheet, get the parent sheet object.
293  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
294  SCH_SHEET* sheet = sheetPin->GetParent();
295  wxCHECK_RET( sheet, wxT( "Sheet label parent not properly set, bad programmer!" ) );
296  sheet->RemovePin( sheetPin );
297  return;
298  }
299 
300  delete aItem;
301 }
302 
303 
305 {
306  return m_rtree.contains( aItem, true );
307 }
308 
309 
310 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType )
311 {
312  EDA_RECT bbox;
313  bbox.SetOrigin( aPosition );
314  bbox.Inflate( aAccuracy );
315 
316  for( auto item : Items().Overlapping( aType, bbox ) )
317  {
318  if( item->HitTest( aPosition, aAccuracy ) )
319  return item;
320  }
321 
322  return nullptr;
323 }
324 
325 
326 std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
327 {
328  std::set<SCH_ITEM*> retval;
329  std::stack<SCH_LINE*> to_search;
330 
331  wxCHECK_MSG( ( aSegment ) && ( aSegment->Type() == SCH_LINE_T ), retval,
332  wxT( "Invalid object pointer." ) );
333 
334  to_search.push( aSegment );
335 
336  while( !to_search.empty() )
337  {
338  auto test_item = to_search.top();
339  to_search.pop();
340 
341  for( auto item : Items().Overlapping( SCH_JUNCTION_T, test_item->GetBoundingBox() ) )
342  {
343  if( test_item->IsEndPoint( item->GetPosition() ) )
344  retval.insert( item );
345  }
346 
347  for( auto item : Items().Overlapping( SCH_LINE_T, test_item->GetBoundingBox() ) )
348  {
349  // Skip connecting lines on different layers (e.g. buses)
350  if( test_item->GetLayer() != item->GetLayer() )
351  continue;
352 
353  auto line = static_cast<SCH_LINE*>( item );
354 
355  if( ( test_item->IsEndPoint( line->GetStartPoint() )
356  && !GetPin( line->GetStartPoint(), NULL, true ) )
357  || ( test_item->IsEndPoint( line->GetEndPoint() )
358  && !GetPin( line->GetEndPoint(), nullptr, true ) ) )
359  {
360  auto result = retval.insert( line );
361 
362  if( result.second )
363  to_search.push( line );
364  }
365  }
366  }
367 
368  return retval;
369 }
370 
371 
372 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew )
373 {
374  enum { WIRES, BUSES } layers;
375 
376  bool has_nonparallel[ sizeof( layers ) ] = { false };
377  int end_count[ sizeof( layers ) ] = { 0 };
378  int pin_count = 0;
379 
380  std::vector<SCH_LINE*> lines[ sizeof( layers ) ];
381 
382  for( auto item : Items().Overlapping( aPosition ) )
383  {
384  if( item->GetEditFlags() & STRUCT_DELETED )
385  continue;
386 
387  if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
388  return false;
389 
390  if( ( item->Type() == SCH_LINE_T ) && ( item->HitTest( aPosition, 0 ) ) )
391  {
392  if( item->GetLayer() == LAYER_WIRE )
393  lines[WIRES].push_back( (SCH_LINE*) item );
394  else if( item->GetLayer() == LAYER_BUS )
395  lines[BUSES].push_back( (SCH_LINE*) item );
396  }
397 
398  if( ( ( item->Type() == SCH_COMPONENT_T ) || ( item->Type() == SCH_SHEET_T ) )
399  && ( item->IsConnected( aPosition ) ) )
400  pin_count++;
401  }
402 
403  for( int i : { WIRES, BUSES } )
404  {
405  bool removed_overlapping = false;
406  bool mid_point = false;
407 
408  for( auto line = lines[i].begin(); line < lines[i].end(); line++ )
409  {
410  if( !(*line)->IsEndPoint( aPosition ) )
411  mid_point = true;
412  else
413  end_count[i]++;
414 
415  for( auto second_line = lines[i].end() - 1; second_line > line; second_line-- )
416  {
417  if( !(*line)->IsParallel( *second_line ) )
418  has_nonparallel[i] = true;
419  else if( !removed_overlapping
420  && (*line)->IsSameQuadrant( *second_line, aPosition ) )
421  {
422  removed_overlapping = true;
423  }
424  }
425  }
426 
430  if( mid_point )
431  end_count[i] += 2;
432 
435  if( removed_overlapping )
436  end_count[i]--;
437  }
438 
439  // If there are three or more endpoints
440  if( pin_count && pin_count + end_count[WIRES] > 2 )
441  return true;
442 
443  // If there is at least one segment that ends on a non-parallel line or
444  // junction of two other lines
445  if( has_nonparallel[WIRES] && end_count[WIRES] > 2 )
446  return true;
447 
448  // Check for bus - bus junction requirements
449  if( has_nonparallel[BUSES] && end_count[BUSES] > 2 )
450  return true;
451 
452  return false;
453 }
454 
455 
456 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
457 {
458  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
459  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
460 
461  SCH_SHEET_PIN* label;
462  SCH_TEXT* text;
463  SCH_CONNECTION conn;
464 
465  switch( aLayer )
466  {
467  case LAYER_BUS:
468 
469  if( GetBus( aPosition ) )
470  return true;
471 
472  label = GetSheetLabel( aPosition );
473 
474  if( label && conn.MightBeBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
475  return true;
476 
477  text = GetLabel( aPosition );
478 
479  if( text && conn.MightBeBusLabel( text->GetText() ) && text->IsConnected( aPosition )
480  && (text->Type() != SCH_LABEL_T) )
481  return true;
482 
483  break;
484 
485  case LAYER_NOTES:
486 
487  if( GetLine( aPosition ) )
488  return true;
489 
490  break;
491 
492  case LAYER_WIRE:
493  if( GetItem( aPosition, Mils2iu( 6 ), SCH_BUS_WIRE_ENTRY_T) )
494  return true;
495 
496  if( GetItem( aPosition, Mils2iu( 6 ), SCH_BUS_BUS_ENTRY_T) )
497  return true;
498 
499  if( GetItem( aPosition, Schematic()->Settings().m_JunctionSize, SCH_JUNCTION_T ) )
500  return true;
501 
502  if( GetPin( aPosition, NULL, true ) )
503  return true;
504 
505  if( GetWire( aPosition ) )
506  return true;
507 
508  text = GetLabel( aPosition );
509 
510  if( text && text->IsConnected( aPosition ) && !conn.MightBeBusLabel( text->GetText() ) )
511  return true;
512 
513  label = GetSheetLabel( aPosition );
514 
515  if( label && label->IsConnected( aPosition ) && !conn.MightBeBusLabel( label->GetText() ) )
516  return true;
517 
518  break;
519 
520  default:
521  break;
522  }
523 
524  return false;
525 }
526 
527 
529 {
530  wxCHECK_RET( Schematic(), "Cannot call SCH_SCREEN::UpdateSymbolLinks with no SCHEMATIC" );
531 
532  wxString msg;
533  std::unique_ptr< LIB_PART > libSymbol;
534  std::vector<SCH_COMPONENT*> symbols;
535  SYMBOL_LIB_TABLE* libs = Schematic()->Prj().SchSymbolLibTable();
536 
537  // This will be a nullptr if an s-expression schematic is loaded.
538  PART_LIBS* legacyLibs = Schematic()->Prj().SchLibs();
539 
540  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
541  symbols.push_back( static_cast<SCH_COMPONENT*>( item ) );
542 
543  // Remove them from the R tree. There bounding box size may change.
544  for( auto symbol : symbols )
545  Remove( symbol );
546 
547  // Clear all existing symbol links.
548  clearLibSymbols();
549 
550  for( auto symbol : symbols )
551  {
552  LIB_PART* tmp = nullptr;
553  libSymbol.reset();
554 
555  // If the symbol is already in the internal library, map the symbol to it.
556  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
557 
558  if( ( it != m_libSymbols.end() ) )
559  {
560  if( aReporter )
561  {
562  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier "
563  "to '%s'. " ),
564  symbol->GetField( REFERENCE )->GetText(),
565  symbol->GetField( VALUE )->GetText(),
566  symbol->GetLibId().Format().wx_str() );
567  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
568  }
569 
570  // Internal library symbols are already flattened so just make a copy.
571  symbol->SetLibSymbol( new LIB_PART( *it->second ) );
572  continue;
573  }
574 
575  if( !symbol->GetLibId().IsValid() )
576  {
577  if( aReporter )
578  {
579  msg.Printf( _( "Schematic symbol reference '%s' library identifier is not "
580  "valid. Unable to link library symbol." ),
581  symbol->GetLibId().Format().wx_str() );
582  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
583  }
584 
585  continue;
586  }
587 
588  // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
589  // is not found in the table so check if the library still exists in the table
590  // before attempting to load the symbol.
591  if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
592  {
593  if( aReporter )
594  {
595  msg.Printf( _( "Symbol library '%s' not found and no fallback cache "
596  "library available. Unable to link library symbol." ),
597  symbol->GetLibId().GetLibNickname().wx_str() );
598  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
599  }
600 
601  continue;
602  }
603 
604  if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
605  {
606  try
607  {
608  tmp = libs->LoadSymbol( symbol->GetLibId() );
609  }
610  catch( const IO_ERROR& ioe )
611  {
612  msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
613  symbol->GetLibId().Format().wx_str() );
614  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
615  }
616  }
617 
618  if( !tmp && legacyLibs )
619  {
620  // If here, only the cache library should be loaded if the loaded schematic
621  // is the legacy file format.
622  wxCHECK2( legacyLibs->GetLibraryCount() == 1, continue );
623 
624  PART_LIB& legacyCacheLib = legacyLibs->at( 0 );
625 
626  // ...and it better be the cache library.
627  wxCHECK2( legacyCacheLib.IsCache(), continue );
628 
629  wxString id = symbol->GetLibId().Format();
630 
631  id.Replace( ':', '_' );
632 
633  if( aReporter )
634  {
635  msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
636  symbol->GetField( REFERENCE )->GetText(),
637  symbol->GetField( VALUE )->GetText(),
638  id );
639  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
640  }
641 
642  tmp = legacyCacheLib.FindPart( id );
643  }
644 
645  if( tmp )
646  {
647  // We want a full symbol not just the top level child symbol.
648  libSymbol = tmp->Flatten();
649  libSymbol->SetParent();
650 
651  m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
652  new LIB_PART( *libSymbol.get() ) } );
653 
654  if( aReporter )
655  {
656  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'. " ),
657  symbol->GetField( REFERENCE )->GetText(),
658  symbol->GetField( VALUE )->GetText(),
659  symbol->GetLibId().Format().wx_str() );
660  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
661  }
662  }
663  else
664  {
665  if( aReporter )
666  {
667  msg.Printf( _( "No library symbol found for schematic symbol '%s %s'. " ),
668  symbol->GetField( REFERENCE )->GetText(),
669  symbol->GetField( VALUE )->GetText() );
670  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
671  }
672  }
673 
674  symbol->SetLibSymbol( libSymbol.release() );
675  }
676 
677  // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
678  // item with the new bbox
679  for( auto symbol : symbols )
680  Append( symbol );
681 }
682 
683 
685 {
686  std::vector<SCH_COMPONENT*> symbols;
687 
688  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
689  symbols.push_back( static_cast<SCH_COMPONENT*>( item ) );
690 
691  for( auto symbol : symbols )
692  {
693  // Changing the symbol may adjust the bbox of the symbol; remove and reinsert it afterwards.
694  m_rtree.remove( symbol );
695 
696  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
697 
698  LIB_PART* libSymbol = nullptr;
699 
700  if( it != m_libSymbols.end() )
701  libSymbol = new LIB_PART( *it->second );
702 
703  symbol->SetLibSymbol( libSymbol );
704 
705  m_rtree.insert( symbol );
706  }
707 }
708 
709 
711 {
712  // Ensure links are up to date, even if a library was reloaded for some reason:
713  std::vector< SCH_ITEM* > junctions;
714  std::vector<SCH_ITEM*> bitmaps;
715  std::vector<SCH_ITEM*> other;
716 
717  for( auto item : Items() )
718  {
719  if( item->IsMoving() || item->IsResized() )
720  continue;
721 
722  if( item->Type() == SCH_JUNCTION_T )
723  junctions.push_back( item );
724  else if( item->Type() == SCH_BITMAP_T )
725  bitmaps.push_back( item );
726  else
727  other.push_back( item );
728  }
729 
731  std::sort( other.begin(), other.end(),
732  []( const SCH_ITEM* a, const SCH_ITEM* b )
733  {
734  if( a->Type() == b->Type() )
735  return a->GetLayer() > b->GetLayer();
736 
737  return a->Type() > b->Type();
738  } );
739 
740  for( auto item : bitmaps )
741  item->Print( aSettings, wxPoint( 0, 0 ) );
742 
743  for( auto item : other )
744  item->Print( aSettings, wxPoint( 0, 0 ) );
745 
746  for( auto item : junctions )
747  item->Print( aSettings, wxPoint( 0, 0 ) );
748 }
749 
750 
751 void SCH_SCREEN::Plot( PLOTTER* aPlotter )
752 {
753  // Ensure links are up to date, even if a library was reloaded for some reason:
754  std::vector< SCH_ITEM* > junctions;
755  std::vector< SCH_ITEM* > bitmaps;
756  std::vector< SCH_ITEM* > other;
757 
758  for( auto item : Items() )
759  {
760  if( item->IsMoving() || item->IsResized() )
761  continue;
762 
763  if( item->Type() == SCH_JUNCTION_T )
764  junctions.push_back( item );
765  else if( item->Type() == SCH_BITMAP_T )
766  bitmaps.push_back( item );
767  else
768  other.push_back( item );
769  }
770 
772  std::sort( other.begin(), other.end(), []( const SCH_ITEM* a, const SCH_ITEM* b ) {
773  if( a->Type() == b->Type() )
774  return a->GetLayer() > b->GetLayer();
775 
776  return a->Type() > b->Type();
777  } );
778 
779  int defaultPenWidth = aPlotter->RenderSettings()->GetDefaultPenWidth();
780 
781  // Bitmaps are drawn first to ensure they are in the background
782  // This is particularly important for the wxPostscriptDC (used in *nix printers) as
783  // the bitmap PS command clears the screen
784  for( SCH_ITEM* item : bitmaps )
785  {
786  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
787  item->Plot( aPlotter );
788  }
789 
790  for( SCH_ITEM* item : other )
791  {
792  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
793  item->Plot( aPlotter );
794  }
795 
796  for( SCH_ITEM* item : junctions )
797  {
798  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
799  item->Plot( aPlotter );
800  }
801 }
802 
803 
805 {
806  if( aItemCount == 0 )
807  return;
808 
809  for( auto& command : aList.m_CommandsList )
810  {
811  command->ClearListAndDeleteItems();
812  delete command;
813  }
814 
815  aList.m_CommandsList.clear();
816 }
817 
818 
820 {
821  for( auto item : Items() )
822  item->ClearTempFlags();
823 }
824 
825 
826 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent,
827  bool aEndPointOnly )
828 {
829  SCH_COMPONENT* component = NULL;
830  LIB_PIN* pin = NULL;
831 
832  for( SCH_ITEM* item : Items().Overlapping( SCH_COMPONENT_T, aPosition ) )
833  {
834  component = static_cast<SCH_COMPONENT*>( item );
835 
836  if( aEndPointOnly )
837  {
838  pin = NULL;
839 
840  if( !component->GetPartRef() )
841  continue;
842 
843  for( pin = component->GetPartRef()->GetNextPin(); pin;
844  pin = component->GetPartRef()->GetNextPin( pin ) )
845  {
846  // Skip items not used for this part.
847  if( component->GetUnit() && pin->GetUnit() &&
848  ( pin->GetUnit() != component->GetUnit() ) )
849  continue;
850 
851  if( component->GetConvert() && pin->GetConvert() &&
852  ( pin->GetConvert() != component->GetConvert() ) )
853  continue;
854 
855  if(component->GetPinPhysicalPosition( pin ) == aPosition )
856  break;
857  }
858  if( pin )
859  break;
860  }
861  else
862  {
863  pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
864 
865  if( pin )
866  break;
867  }
868  }
869 
870  if( pin && aComponent )
871  *aComponent = component;
872 
873  return pin;
874 }
875 
876 
878 {
879  SCH_SHEET_PIN* sheetPin = nullptr;
880 
881  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
882  {
883  auto sheet = static_cast<SCH_SHEET*>( item );
884 
885  sheetPin = sheet->GetPin( aPosition );
886 
887  if( sheetPin )
888  break;
889  }
890 
891  return sheetPin;
892 }
893 
894 
895 size_t SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions )
896 {
897  size_t count = 0;
898 
899  for( SCH_ITEM* item : Items() )
900  {
901  if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
902  count++;
903  }
904 
905  return count;
906 }
907 
908 
910 {
911 
912  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
913  {
914  SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
915 
916  component->ClearAnnotation( aSheetPath );
917 
918  // Clear the modified component flag set by component->ClearAnnotation
919  // because we do not use it here and we should not leave this flag set,
920  // when an editing is finished:
921  component->ClearFlags();
922  }
923 }
924 
925 
927 {
928  if( GetClientSheetPaths().size() <= 1 ) // No need for alternate reference
929  return;
930 
931  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
932  {
933  auto component = static_cast<SCH_COMPONENT*>( item );
934 
935  // Add (when not existing) all sheet path entries
936  for( const auto& sheet : GetClientSheetPaths() )
937  component->AddSheetPathReferenceEntryIfMissing( sheet.Path() );
938  }
939 }
940 
941 
942 void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems )
943 {
944  for( SCH_ITEM* item : Items() )
945  {
946  if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
947  aItems->push_back( item );
948  }
949 }
950 
951 
952 void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems )
953 {
954  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
955  aItems->push_back( item );
956 
957  std::sort( aItems->begin(), aItems->end(),
958  []( EDA_ITEM* a, EDA_ITEM* b ) -> bool
959  {
960  long a_order = 0;
961  long b_order = 0;
962 
963  for( const SCH_FIELD& field : static_cast<SCH_SHEET*>( a )->GetFields() )
964  {
965  if( field.GetName().CmpNoCase( wxT( "Order" ) ) == 0 )
966  {
967  field.GetText().ToLong( &a_order );
968  break;
969  }
970  }
971 
972  for( const SCH_FIELD& field : static_cast<SCH_SHEET*>( b )->GetFields() )
973  {
974  if( field.GetName().CmpNoCase( wxT( "Order" ) ) == 0 )
975  {
976  field.GetText().ToLong( &b_order );
977  break;
978  }
979  }
980 
981  if( a_order == b_order )
982  {
983  if( a->GetPosition().x == b->GetPosition().x )
984  return a->GetPosition().y < b->GetPosition().y;
985 
986  return a->GetPosition().x < b->GetPosition().x;
987  }
988 
989  return a_order < b_order;
990  } );
991 }
992 
993 
995 {
996  std::vector< DANGLING_END_ITEM > endPoints;
997  bool hasStateChanged = false;
998 
999  for( SCH_ITEM* item : Items() )
1000  item->GetEndPoints( endPoints );
1001 
1002  for( SCH_ITEM* item : Items() )
1003  {
1004  if( item->UpdateDanglingState( endPoints, aPath ) )
1005  hasStateChanged = true;
1006  }
1007 
1008  return hasStateChanged;
1009 }
1010 
1011 
1012 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
1013  SCH_LINE_TEST_T aSearchType )
1014 {
1015  // an accuracy of 0 had problems with rounding errors; use at least 1
1016  aAccuracy = std::max( aAccuracy, 1 );
1017 
1018  for( SCH_ITEM* item : Items() )
1019  {
1020  if( item->Type() != SCH_LINE_T )
1021  continue;
1022 
1023  if( item->GetLayer() != aLayer )
1024  continue;
1025 
1026  if( !item->HitTest( aPosition, aAccuracy ) )
1027  continue;
1028 
1029  switch( aSearchType )
1030  {
1031  case ENTIRE_LENGTH_T:
1032  return (SCH_LINE*) item;
1033 
1034  case EXCLUDE_END_POINTS_T:
1035  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1036  return (SCH_LINE*) item;
1037  break;
1038 
1039  case END_POINTS_ONLY_T:
1040  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1041  return (SCH_LINE*) item;
1042  }
1043  }
1044 
1045  return NULL;
1046 }
1047 
1048 
1049 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
1050 {
1051  for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1052  {
1053  switch( item->Type() )
1054  {
1055  case SCH_LABEL_T:
1056  case SCH_GLOBAL_LABEL_T:
1057  case SCH_HIER_LABEL_T:
1058  if( item->HitTest( aPosition, aAccuracy ) )
1059  return (SCH_TEXT*) item;
1060 
1061  break;
1062 
1063  default:
1064  ;
1065  }
1066  }
1067 
1068  return NULL;
1069 }
1070 
1071 
1072 bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
1073  const wxString& aFootPrint, bool aSetVisible )
1074 {
1075  SCH_COMPONENT* component;
1076  bool found = false;
1077 
1078  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
1079  {
1080  component = static_cast<SCH_COMPONENT*>( item );
1081 
1082  if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
1083  {
1084  // Found: Init Footprint Field
1085 
1086  /* Give a reasonable value to the field position and
1087  * orientation, if the text is empty at position 0, because
1088  * it is probably not yet initialized
1089  */
1090  SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
1091  if( fpfield->GetText().IsEmpty()
1092  && ( fpfield->GetTextPos() == component->GetPosition() ) )
1093  {
1094  fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
1095  fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
1096  fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
1097 
1098  if( fpfield->GetTextAngle() == 0.0 )
1099  fpfield->Offset( wxPoint( 0, Mils2iu( 100 ) ) );
1100  else
1101  fpfield->Offset( wxPoint( Mils2iu( 100 ), 0 ) );
1102  }
1103 
1104  fpfield->SetText( aFootPrint );
1105  fpfield->SetVisible( aSetVisible );
1106 
1107  found = true;
1108  }
1109  }
1110 
1111  return found;
1112 }
1113 
1114 
1116 {
1117  wxCHECK( aLibSymbol, /* void */ );
1118 
1119  wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
1120 
1121  auto it = m_libSymbols.find( libSymbolName );
1122 
1123  if( it != m_libSymbols.end() )
1124  {
1125  delete it->second;
1126  m_libSymbols.erase( it );
1127  }
1128 
1129  m_libSymbols[libSymbolName] = aLibSymbol;
1130 }
1131 
1132 
1133 void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1134 {
1135  m_aliases.insert( aAlias );
1136 }
1137 
1138 
1139 #if defined(DEBUG)
1140 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1141 {
1142  // for now, make it look like XML, expand on this later.
1143  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1144 
1145  for( const SCH_ITEM* item : Items() )
1146  item->Show( nestLevel + 1, os );
1147 
1148  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1149 }
1150 #endif
1151 
1152 
1154 {
1155  m_index = 0;
1156  buildScreenList( aSheet );
1157 }
1158 
1159 
1161 {
1162 }
1163 
1164 
1166 {
1167  m_index = 0;
1168 
1169  if( m_screens.size() > 0 )
1170  return m_screens[0];
1171 
1172  return NULL;
1173 }
1174 
1175 
1177 {
1178  if( m_index < m_screens.size() )
1179  m_index++;
1180 
1181  return GetScreen( m_index );
1182 }
1183 
1184 
1185 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1186 {
1187  if( aIndex < m_screens.size() )
1188  return m_screens[ aIndex ];
1189 
1190  return NULL;
1191 }
1192 
1193 
1194 SCH_SHEET* SCH_SCREENS::GetSheet( unsigned int aIndex ) const
1195 {
1196  if( aIndex < m_sheets.size() )
1197  return m_sheets[ aIndex ];
1198 
1199  return NULL;
1200 }
1201 
1202 
1204 {
1205  if( aScreen == NULL )
1206  return;
1207 
1208  for( const SCH_SCREEN* screen : m_screens )
1209  {
1210  if( screen == aScreen )
1211  return;
1212  }
1213 
1214  m_screens.push_back( aScreen );
1215  m_sheets.push_back( aSheet );
1216 }
1217 
1218 
1220 {
1221  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1222  {
1223  SCH_SCREEN* screen = aSheet->GetScreen();
1224 
1225  addScreenToList( screen, aSheet );
1226 
1227  for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
1228  buildScreenList( static_cast<SCH_SHEET*>( item ) );
1229  }
1230 }
1231 
1232 
1234 {
1235  for( SCH_SCREEN* screen : m_screens )
1236  screen->ClearAnnotation( NULL );
1237 }
1238 
1239 
1241 {
1242  SCH_SCREEN* first = GetFirst();
1243 
1244  if( !first )
1245  return;
1246 
1247  SCHEMATIC* sch = first->Schematic();
1248 
1249  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" );
1250 
1251  // Clear the annotation for the components inside new sheetpaths
1252  // not already in aInitialSheetList
1253  SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths
1254  screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1255 
1256  // Search for new sheet paths, not existing in aInitialSheetPathList
1257  // and existing in sheetpathList
1258  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1259  {
1260  bool path_exists = false;
1261 
1262  for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1263  {
1264  if( existing_sheetpath.Path() == sheetpath.Path() )
1265  {
1266  path_exists = true;
1267  break;
1268  }
1269  }
1270 
1271  if( !path_exists )
1272  {
1273  // A new sheet path is found: clear the annotation corresponding to this new path:
1274  SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1275 
1276  // Clear annotation and create the AR for this path, if not exists,
1277  // when the screen is shared by sheet paths.
1278  // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1279  // reference default value and takes the latest displayed value
1280  curr_screen->EnsureAlternateReferencesExist();
1281  curr_screen->ClearAnnotation( &sheetpath );
1282  }
1283  }
1284 }
1285 
1286 
1288 {
1289  std::vector<SCH_ITEM*> items;
1290  int count = 0;
1291 
1292  auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1293  {
1294  return a->m_Uuid < b->m_Uuid;
1295  };
1296 
1297  std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1298 
1299  for( SCH_SCREEN* screen : m_screens )
1300  screen->GetHierarchicalItems( &items );
1301 
1302  if( items.size() < 2 )
1303  return 0;
1304 
1305  for( EDA_ITEM* item : items )
1306  {
1307  if( !unique_stamps.insert( item ).second )
1308  {
1309  // Reset to fully random UUID. This may lose reference, but better to be
1310  // deterministic about it rather than to have duplicate UUIDs with random
1311  // side-effects.
1312  const_cast<KIID&>( item->m_Uuid ) = KIID();
1313  count++;
1314  }
1315  }
1316 
1317  return count;
1318 }
1319 
1320 
1322 {
1323  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1324  {
1325  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1326  {
1327  if( item == aMarker )
1328  {
1329  screen->DeleteItem( item );
1330  return;
1331  }
1332  }
1333  }
1334 }
1335 
1336 
1337 void SCH_SCREENS::DeleteMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType, int aErrorCode )
1338 {
1339  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1340  {
1341  std::vector<SCH_ITEM*> markers;
1342 
1343  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1344  {
1345  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
1346  RC_ITEM* rcItem = marker->GetRCItem();
1347 
1348  if( marker->GetMarkerType() == aMarkerType &&
1349  ( aErrorCode == ERCE_UNSPECIFIED || rcItem->GetErrorCode() == aErrorCode ) )
1350  {
1351  markers.push_back( item );
1352  }
1353  }
1354 
1355  for( SCH_ITEM* marker : markers )
1356  screen->DeleteItem( marker );
1357  }
1358 }
1359 
1360 
1362 {
1363  DeleteMarkers( aMarkerType, ERCE_UNSPECIFIED );
1364 }
1365 
1366 
1368 {
1369  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1370  screen->UpdateSymbolLinks( aReporter );
1371 
1372  SCH_SCREEN* first = GetFirst();
1373 
1374  if( !first )
1375  return;
1376 
1377  SCHEMATIC* sch = first->Schematic();
1378 
1379  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" );
1380 
1381  SCH_SHEET_LIST sheets = sch->GetSheets();
1382 
1383  // All of the library symbols have been replaced with copies so the connection graph
1384  // pointer are stale.
1385  if( sch->ConnectionGraph() )
1386  sch->ConnectionGraph()->Recalculate( sheets, true );
1387 }
1388 
1389 
1391 {
1392  std::vector<SCH_SCREEN*> screens;
1393  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1394  screens.push_back( screen );
1395 
1396  size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
1397  screens.size() );
1398 
1399  std::atomic<size_t> nextScreen( 0 );
1400  std::vector<std::future<size_t>> returns( parallelThreadCount );
1401 
1402  auto update_lambda = [&screens, &nextScreen]() -> size_t
1403  {
1404  for( auto i = nextScreen++; i < screens.size(); i = nextScreen++ )
1405  screens[i]->TestDanglingEnds();
1406 
1407  return 1;
1408  };
1409 
1410  if( parallelThreadCount == 1 )
1411  update_lambda();
1412  else
1413  {
1414  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1415  returns[ii] = std::async( std::launch::async, update_lambda );
1416 
1417  // Finalize the threads
1418  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1419  returns[ii].wait();
1420  }
1421 }
1422 
1423 
1425 {
1426  SCH_SCREEN* screen;
1427  unsigned cnt = 0;
1428 
1429  for( screen = GetFirst(); screen; screen = GetNext() )
1430  {
1431  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1432  {
1433  cnt++;
1434  auto symbol = static_cast<SCH_COMPONENT*>( item );
1435 
1436  if( !symbol->GetLibId().GetLibNickname().empty() )
1437  return false;
1438  }
1439  }
1440 
1441  return cnt != 0;
1442 }
1443 
1444 
1445 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1446 {
1447  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1448  {
1449  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1450  {
1451  auto symbol = static_cast<SCH_COMPONENT*>( item );
1452  auto& nickname = symbol->GetLibId().GetLibNickname();
1453 
1454  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1455  aLibNicknames.Add( nickname );
1456  }
1457  }
1458 
1459  return aLibNicknames.GetCount();
1460 }
1461 
1462 
1463 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1464 {
1465  SCH_SCREEN* screen;
1466  int cnt = 0;
1467 
1468  for( screen = GetFirst(); screen; screen = GetNext() )
1469  {
1470  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1471  {
1472  auto symbol = static_cast<SCH_COMPONENT*>( item );
1473 
1474  if( symbol->GetLibId().GetLibNickname() != aFrom )
1475  continue;
1476 
1477  LIB_ID id = symbol->GetLibId();
1478  id.SetLibNickname( aTo );
1479  symbol->SetLibId( id );
1480  cnt++;
1481  }
1482  }
1483 
1484  return cnt;
1485 }
1486 
1487 
1488 bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
1489 {
1490  for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1491  {
1492  if( screen->GetFileName() == aSchematicFileName )
1493  return true;
1494  }
1495 
1496  return false;
1497 }
1498 
1499 
1500 bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
1501 {
1502  wxString lhsLower;
1503  wxString rhsLower;
1504  wxFileName lhs;
1505  wxFileName rhs = aSchematicFileName;
1506 
1507  wxCHECK( rhs.IsAbsolute(), false );
1508 
1509  for( const SCH_SCREEN* screen : m_screens )
1510  {
1511  lhs = screen->GetFileName();
1512 
1513  if( lhs.GetPath() != rhs.GetPath() )
1514  continue;
1515 
1516  lhsLower = lhs.GetFullName().Lower();
1517  rhsLower = rhs.GetFullName().Lower();
1518 
1519  if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
1520  return true;
1521  }
1522 
1523  return false;
1524 }
1525 
1526 
1528 {
1529  SCH_SCREEN* first = GetFirst();
1530 
1531  if( !first )
1532  return;
1533 
1534  SCHEMATIC* sch = first->Schematic();
1535 
1536  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" );
1537 
1538  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1539  curr_screen->GetClientSheetPaths().clear();
1540 
1541  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1542  {
1543  SCH_SCREEN* used_screen = sheetpath.LastScreen();
1544 
1545  // SEarch for the used_screen in list and add this unique sheet path:
1546  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1547  {
1548  if( used_screen == curr_screen )
1549  {
1550  curr_screen->GetClientSheetPaths().push_back( sheetpath );
1551  break;
1552  }
1553  }
1554  }
1555 }
SCH_SHEET_LIST.
void insert(SCH_ITEM *aItem)
Function Insert() Inserts an item into the tree.
Definition: sch_rtree.h:62
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:252
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_COMPONENT **aComponent=NULL, bool aEndPointOnly=false)
Test the screen for a component pin item at aPosition.
Definition: sch_screen.cpp:826
static bool MightBeBusLabel(const wxString &aLabel)
Test if aLabel looks like a bus notation.
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:245
SCH_SCREEN * GetNext()
int m_ScreenNumber
Definition: base_screen.h:85
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
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:168
LIB_ID GetLibId() const override
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:92
RC_ITEM * GetRCItem()
Function GetReporter returns the DRC_ITEM held within this MARKER so that its interface may be used.
Definition: marker_base.h:117
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:42
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:132
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:372
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false)
Updates the connection graph for the given list of sheets.
void clearLibSymbols()
Definition: sch_screen.cpp:102
RC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: rc_item.h:77
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:134
wxString GetSchSymbolLibraryName() const
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
EE_TYPE Overlapping(const EDA_RECT &aRect)
Definition: sch_rtree.h:224
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:246
void SetVisible(bool aVisible)
Definition: eda_text.h:184
void addScreenToList(SCH_SCREEN *aScreen, SCH_SHEET *aSheet)
int m_refCount
Number of sheets referencing this screen.
Definition: sch_screen.h:99
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
double GetTextAngle() const
Definition: eda_text.h:173
void GetSheets(std::vector< SCH_ITEM * > *aItems)
Similar to GetItems().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
Definition: sch_screen.cpp:952
LIB_PART * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_PART having aName from the library given by aNickname.
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
int GetLibraryCount()
void Clear()
Definition: title_block.h:116
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:237
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
Definition: sch_screen.cpp:926
void SetSchSymbolLibraryName(const wxString &aName)
The name of the symbol in the schematic library symbol list.
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
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:120
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:200
virtual const wxPoint GetPosition() const
Definition: base_struct.h:337
bool contains(SCH_ITEM *aItem, bool aRobust=false)
Determine if a given item exists in the tree.
Definition: sch_rtree.h:122
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:50
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.
SCH_SCREEN(EDA_ITEM *aParent=nullptr)
Constructor.
Definition: sch_screen.cpp:70
unsigned int m_index
Definition: sch_screen.h:555
UNDO_REDO_CONTAINER is a holder to handle alist of undo (or redo) command.
Definition: common.h:68
bool HasItems(KICAD_T aItemType) const
Definition: sch_screen.cpp:125
int GetUnit() const
Definition: lib_item.h:295
#define VALUE
int GetUnit() const
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:287
void UpdateLocalLibSymbolLinks()
Initialize the LIB_PART reference for each SCH_COMPONENT found in this schematic with the local proje...
Definition: sch_screen.cpp:684
std::vector< SCH_SHEET * > m_sheets
Definition: sch_screen.h:554
TITLE_BLOCK m_titles
Definition: sch_screen.h:113
bool remove(SCH_ITEM *aItem)
Function Remove() Removes an item from the tree.
Definition: sch_rtree.h:78
PAGE_INFO m_paper
The size of the paper to print or plot on.
Definition: sch_screen.h:111
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
bool m_Center
Center on screen.
Definition: base_screen.h:71
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:283
SCH_LINE_TEST_T
Definition: sch_screen.h:69
BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:44
iterator end()
Definition: sch_rtree.h:253
Class LIB_PIN definition.
const wxSize & GetTextSize() const
Definition: eda_text.h:238
EE_RTREE m_rtree
Definition: sch_screen.h:118
const wxPoint GetPosition() const override
virtual void ClearUndoRedoList()
Function ClearUndoRedoList clear undo and redo list, using ClearUndoORRedoList() picked items are del...
Definition: base_screen.cpp:73
int GetErrorCode() const
Definition: rc_item.h:160
Define a library symbol object.
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:126
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
EDA_ITEM * GetParent() const
Definition: base_struct.h:195
void Print(RENDER_SETTINGS *aSettings)
Print all the items in the screen to aDC.
Definition: sch_screen.cpp:710
void GetHierarchicalItems(std::vector< SCH_ITEM * > *aItems)
Add all schematic sheet and component objects in the screen to aItems.
Definition: sch_screen.cpp:942
SCH_SHEET_PIN * GetSheetLabel(const wxPoint &aPosition)
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:877
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:84
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:455
SCH_SHEET_PATH.
std::unique_ptr< LIB_PART > & GetPartRef()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
void DeleteMarker(SCH_MARKER *aMarker)
Delete a specific marker.
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
int GetConvert() const
Definition: lib_item.h:298
size_t CountConnectedItems(const wxPoint &aPos, bool aTestJunctions)
Definition: sch_screen.cpp:895
iterator end()
Definition: sch_rtree.h:213
UTF8 Format() const
Definition: lib_id.cpp:237
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:219
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
void Plot(PLOTTER *aPlotter)
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:751
YYCODETYPE lhs
const KIID m_Uuid
Definition: base_struct.h:162
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:271
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
A collection of PART_LIB objects.
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:117
Base plotter engine class.
Definition: plotter.h:114
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_PART reference for each SCH_COMPONENT found in this schematic from the project SYM...
Definition: sch_screen.cpp:528
SCH_SHEET & Root() const
Definition: schematic.h:97
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:147
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer)
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:456
iterator begin()
Definition: sch_rtree.h:208
see class PGM_BASE
void AddLibSymbol(LIB_PART *aLibSymbol)
Add aLibSymbol to the the library symbol map.
void TestDanglingEnds()
SCH_TEXT * GetLabel(const wxPoint &aPosition, int aAccuracy=0)
Return a label item located at aPosition.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Adds a bus alias definition (and transfers ownership of the pointer)
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:553
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
void ClearAnnotation()
Clear the annotation for all components in the hierarchy.
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:106
iterator begin()
Definition: sch_rtree.h:248
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
#define _(s)
Definition: 3d_actions.cpp:33
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:93
SCH_SCREENS(SCH_SHEET *aSheet)
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:124
EE_RTREE & Items()
Definition: sch_screen.h:162
wxString wx_str() const
Definition: utf8.cpp:51
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition: sch_rtree.h:181
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
SCH_SHEET * GetSheet(unsigned int aIndex) const
Schematic symbol object.
Definition: sch_component.h:88
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
The common library.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:233
int GetDefaultPenWidth() const
int m_NumberOfScreens
Definition: base_screen.h:86
const wxPoint & GetTextPos() const
Definition: eda_text.h:247
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:909
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2950
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Definition: sch_screen.h:209
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T)
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:310
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
int GetConvert() const
SCH_SCREEN * GetFirst()
SCH_SCREEN * GetScreen(unsigned int aIndex) const
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:819
void Update(SCH_ITEM *aItem)
Updates aItem's bounding box in the tree.
Definition: sch_screen.cpp:238
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:166
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:804
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:183
Definition of the NETLIST_OBJECT class.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_PART reference for each SCH_COMPONENT found in the full schematic.
bool CheckIfOnDrawList(SCH_ITEM *st)
Definition: sch_screen.cpp:304
const LIB_ID & GetLibId() const
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
Object used to load, save, search, and otherwise manipulate symbol library files.
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nickames into aLibNicknames.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:186
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126
void clear()
Function RemoveAll() Removes all items from the RTree.
Definition: sch_rtree.h:108
bool IsConnected(const wxPoint &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:138
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:550
void DeleteMarkers(enum MARKER_BASE::TYPEMARKER aMarkerTyp, int aErrorCode)
Delete all markers of a particular type and error code.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
void IncRefCount()
Definition: sch_screen.cpp:111
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
bool TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr)
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:994
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_screen.h:179
std::map< wxString, LIB_PART * > m_libSymbols
Library symbols required for this schematic.
Definition: sch_screen.h:127
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.
std::set< SCH_ITEM * > MarkConnections(SCH_LINE *aSegment)
Return all wires and junctions connected to aSegment which are not connected any component pin.
Definition: sch_screen.cpp:326
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Definition: sch_screen.h:461