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-2021 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 <eda_rect.h>
33 #include <id.h>
34 #include <kicad_string.h>
35 #include <kiway.h>
36 #include <pgm_base.h>
37 #include <plotter.h>
38 #include <project.h>
39 #include <reporter.h>
40 #include <sch_draw_panel.h>
41 #include <sch_edit_frame.h>
42 #include <sch_item.h>
43 
44 #include <class_library.h>
45 #include <connection_graph.h>
46 #include <lib_pin.h>
47 #include <sch_symbol.h>
48 #include <sch_junction.h>
49 #include <sch_line.h>
50 #include <sch_marker.h>
51 #include <sch_sheet.h>
52 #include <sch_sheet_pin.h>
53 #include <sch_text.h>
54 #include <schematic.h>
55 #include <symbol_lib_table.h>
56 #include <tool/common_tools.h>
57 
58 #include <algorithm>
59 
60 // TODO(JE) Debugging only
61 #include <profile.h>
62 #include "sch_bus_entry.h"
63 
65  BASE_SCREEN( aParent, SCH_SCREEN_T ),
66  m_fileFormatVersionAtLoad( 0 ),
67  m_paper( wxT( "A4" ) )
68 {
70  m_refCount = 0;
71  m_zoomInitialized = false;
72  m_LastZoomLevel = 1.0;
73 
74  // Suitable for schematic only. For symbol_editor and viewlib, must be set to true
75  m_Center = false;
76 
77  InitDataPoints( m_paper.GetSizeIU() );
78 }
79 
80 
82 {
84  FreeDrawList();
85 }
86 
87 
89 {
90  wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr,
91  "SCH_SCREEN must have a SCHEMATIC parent!" );
92 
93  return static_cast<SCHEMATIC*>( GetParent() );
94 }
95 
96 
98 {
99  for( auto libSymbol : m_libSymbols )
100  delete libSymbol.second;
101 
102  m_libSymbols.clear();
103 }
104 
105 
107 {
108  m_refCount++;
109 }
110 
111 
113 {
114  wxCHECK_RET( m_refCount != 0,
115  wxT( "Screen reference count already zero. Bad programmer!" ) );
116  m_refCount--;
117 }
118 
119 
120 bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const
121 {
122  EE_RTREE::EE_TYPE sheets = m_rtree.OfType( aItemType );
123 
124  return sheets.begin() != sheets.end();
125 }
126 
127 
129 {
130  if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
131  {
132  // Ensure the item can reach the SCHEMATIC through this screen
133  aItem->SetParent( this );
134 
135  if( aItem->Type() == SCH_COMPONENT_T )
136  {
137  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( aItem );
138 
139  if( symbol->GetPartRef() )
140  {
141  symbol->GetPartRef()->GetDrawItems().sort();
142 
143  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
144 
145  if( it == m_libSymbols.end() || !it->second )
146  {
148  new LIB_PART( *symbol->GetPartRef() );
149  }
150  else
151  {
152  // The original library symbol may have changed since the last time
153  // it was added to the schematic. If it has changed, then a new name
154  // must be created for the library symbol list to prevent all of the
155  // other schematic symbols referencing that library symbol from changing.
156  LIB_PART* foundSymbol = it->second;
157 
158  foundSymbol->GetDrawItems().sort();
159 
160  if( *foundSymbol != *symbol->GetPartRef() )
161  {
162  int cnt = 1;
163  wxString newName;
164 
165  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
166 
167  while( m_libSymbols.find( newName ) != m_libSymbols.end() )
168  {
169  cnt += 1;
170  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
171  }
172 
173  symbol->SetSchSymbolLibraryName( newName );
174  m_libSymbols[newName] = new LIB_PART( *symbol->GetPartRef() );
175  }
176  }
177  }
178  }
179 
180  m_rtree.insert( aItem );
182  }
183 }
184 
185 
187 {
188  wxCHECK_RET( aScreen, "Invalid screen object." );
189 
190  // No need to descend the hierarchy. Once the top level screen is copied, all of it's
191  // children are copied as well.
192  for( auto aItem : aScreen->m_rtree )
193  Append( aItem );
194 
195  aScreen->Clear( false );
196 }
197 
198 
199 void SCH_SCREEN::Clear( bool aFree )
200 {
201  if( aFree )
202  {
203  FreeDrawList();
204  clearLibSymbols();
205  }
206  else
207  {
208  m_rtree.clear();
209  }
210 
211  // Clear the project settings
213 
214  m_titles.Clear();
215 }
216 
217 
219 {
220  // We don't know which order we will encounter dependent items (e.g. pins or fields), so
221  // we store the items to be deleted until we've fully cleared the tree before deleting
222  std::vector<SCH_ITEM*> delete_list;
223 
224  std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
225  []( SCH_ITEM* aItem )
226  {
227  return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
228  } );
229 
230  m_rtree.clear();
231 
232  for( auto item : delete_list )
233  delete item;
234 }
235 
236 
238 {
239  if( Remove( aItem ) )
240  Append( aItem );
241 }
242 
243 
245 {
246  bool retv = m_rtree.remove( aItem );
247 
248  // Check if the library symbol for the removed schematic symbol is still required.
249  if( retv && aItem->Type() == SCH_COMPONENT_T )
250  {
251  SCH_COMPONENT* removedSymbol = static_cast<SCH_COMPONENT*>( aItem );
252 
253  bool removeUnusedLibSymbol = true;
254 
255  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
256  {
257  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
258 
259  if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
260  {
261  removeUnusedLibSymbol = false;
262  break;
263  }
264  }
265 
266  if( removeUnusedLibSymbol )
267  {
268  auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
269 
270  if( it != m_libSymbols.end() )
271  {
272  delete it->second;
273  m_libSymbols.erase( it );
274  }
275  }
276  }
277 
278  return retv;
279 }
280 
281 
283 {
284  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
285 
286  // Markers are not saved in the file, no need to flag as modified.
287  // TODO: Maybe we should have a listing somewhere of items that aren't saved?
288  if( aItem->Type() != SCH_MARKER_T )
289  SetModify();
290 
291  Remove( aItem );
292 
293  if( aItem->Type() == SCH_SHEET_PIN_T )
294  {
295  // This structure is attached to a sheet, get the parent sheet object.
296  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
297  SCH_SHEET* sheet = sheetPin->GetParent();
298  wxCHECK_RET( sheet, wxT( "Sheet pin parent not properly set, bad programmer!" ) );
299  sheet->RemovePin( sheetPin );
300  return;
301  }
302 
303  delete aItem;
304 }
305 
306 
307 bool SCH_SCREEN::CheckIfOnDrawList( const SCH_ITEM* aItem ) const
308 {
309  return m_rtree.contains( aItem, true );
310 }
311 
312 
313 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
314 {
315  EDA_RECT bbox;
316  bbox.SetOrigin( aPosition );
317  bbox.Inflate( aAccuracy );
318 
319  for( SCH_ITEM* item : Items().Overlapping( aType, bbox ) )
320  {
321  if( item->HitTest( aPosition, aAccuracy ) )
322  return item;
323  }
324 
325  return nullptr;
326 }
327 
328 
329 std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
330 {
331  std::set<SCH_ITEM*> retval;
332  std::stack<SCH_LINE*> to_search;
333 
334  wxCHECK_MSG( aSegment && aSegment->Type() == SCH_LINE_T, retval, wxT( "Invalid pointer." ) );
335 
336  to_search.push( aSegment );
337 
338  while( !to_search.empty() )
339  {
340  SCH_LINE* test_item = to_search.top();
341  to_search.pop();
342 
343  for( SCH_ITEM* item : Items().Overlapping( SCH_JUNCTION_T, test_item->GetBoundingBox() ) )
344  {
345  if( test_item->IsEndPoint( item->GetPosition() ) )
346  retval.insert( item );
347  }
348 
349  for( SCH_ITEM* item : Items().Overlapping( SCH_LINE_T, test_item->GetBoundingBox() ) )
350  {
351  // Skip connecting lines on different layers (e.g. buses)
352  if( test_item->GetLayer() != item->GetLayer() )
353  continue;
354 
355  SCH_LINE* line = static_cast<SCH_LINE*>( item );
356 
357  if( ( test_item->IsEndPoint( line->GetStartPoint() )
358  && !GetPin( line->GetStartPoint(), NULL, true ) )
359  || ( test_item->IsEndPoint( line->GetEndPoint() )
360  && !GetPin( line->GetEndPoint(), nullptr, true ) ) )
361  {
362  auto result = retval.insert( line );
363 
364  if( result.second )
365  to_search.push( line );
366  }
367  }
368  }
369 
370  return retval;
371 }
372 
373 
374 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew ) const
375 {
376  enum layers { WIRES = 0, BUSES };
377 
378  bool breakLines[ 2 ] = { false };
379  std::unordered_set<int> exitAngles[ 2 ];
380  std::vector<const SCH_LINE*> midPointLines[ 2 ];
381 
382  // A pin at 90º still shouldn't match a line at 90º so just give pins unique numbers
383  int uniqueAngle = 10000;
384 
385  for( const SCH_ITEM* item : Items().Overlapping( aPosition ) )
386  {
387  if( item->GetEditFlags() & STRUCT_DELETED )
388  continue;
389 
390  switch( item->Type() )
391  {
392  case SCH_JUNCTION_T:
393  if( aNew && item->HitTest( aPosition, -1 ) )
394  return false;
395 
396  break;
397 
398  case SCH_LINE_T:
399  {
400  const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
401  int layer;
402 
403  if( line->GetStartPoint() == line->GetEndPoint() )
404  break;
405  else if( line->GetLayer() == LAYER_WIRE )
406  layer = WIRES;
407  else if( line->GetLayer() == LAYER_BUS )
408  layer = BUSES;
409  else
410  break;
411 
412  if( line->IsConnected( aPosition ) )
413  {
414  breakLines[ layer ] = true;
415  exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
416  }
417  else if( line->HitTest( aPosition, -1 ) )
418  {
419  // Defer any line midpoints until we know whether or not we're breaking them
420  midPointLines[ layer ].push_back( line );
421  }
422  }
423  break;
424 
426  case SCH_COMPONENT_T:
427  case SCH_SHEET_T:
428  if( item->IsConnected( aPosition ) )
429  {
430  breakLines[ WIRES ] = true;
431  exitAngles[ WIRES ].insert( uniqueAngle++ );
432  }
433 
434  break;
435 
436  default:
437  break;
438  }
439  }
440 
441  for( int layer : { WIRES, BUSES } )
442  {
443  if( breakLines[ layer ] )
444  {
445  for( const SCH_LINE* line : midPointLines[ layer ] )
446  {
447  exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
448  exitAngles[ layer ].insert( line->GetReverseAngleFrom( aPosition ) );
449  }
450  }
451  }
452 
453  return exitAngles[ WIRES ].size() >= 3 || exitAngles[ BUSES ].size() >= 3;
454 }
455 
456 
457 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer ) const
458 {
459  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
460  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
461 
462  switch( aLayer )
463  {
464  case LAYER_BUS:
465  {
466  if( GetBus( aPosition ) )
467  return true;
468 
469  SCH_SHEET_PIN* sheetPin = GetSheetPin( aPosition );
470 
471  if( sheetPin && sheetPin->IsConnected( aPosition ) )
472  return true;
473 
474  SCH_TEXT* label = GetLabel( aPosition );
475 
476  if( label && label->IsConnected( aPosition ) )
477  return true;
478  }
479  break;
480 
481  case LAYER_NOTES:
482  {
483  if( GetLine( aPosition ) )
484  return true;
485  }
486  break;
487 
488  case LAYER_WIRE:
489  {
490  if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T) )
491  return true;
492 
493  if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
494  return true;
495 
496  if( GetPin( aPosition, NULL, true ) )
497  return true;
498 
499  if( GetWire( aPosition ) )
500  return true;
501 
502  SCH_TEXT* label = GetLabel( aPosition, 1 );
503 
504  if( label && label->IsConnected( aPosition ) )
505  return true;
506 
507  SCH_SHEET_PIN* sheetPin = GetSheetPin( aPosition );
508 
509  if( sheetPin && sheetPin->IsConnected( aPosition ) )
510  return true;
511  }
512  break;
513 
514  default:
515  break;
516  }
517 
518  return false;
519 }
520 
521 
523 {
524  wxCHECK_RET( Schematic(), "Cannot call SCH_SCREEN::UpdateSymbolLinks with no SCHEMATIC" );
525 
526  wxString msg;
527  std::unique_ptr< LIB_PART > libSymbol;
528  std::vector<SCH_COMPONENT*> symbols;
529  SYMBOL_LIB_TABLE* libs = Schematic()->Prj().SchSymbolLibTable();
530 
531  // This will be a nullptr if an s-expression schematic is loaded.
532  PART_LIBS* legacyLibs = Schematic()->Prj().SchLibs();
533 
534  for( auto item : Items().OfType( SCH_COMPONENT_T ) )
535  symbols.push_back( static_cast<SCH_COMPONENT*>( item ) );
536 
537  // Remove them from the R tree. There bounding box size may change.
538  for( auto symbol : symbols )
539  Remove( symbol );
540 
541  // Clear all existing symbol links.
542  clearLibSymbols();
543 
544  for( auto symbol : symbols )
545  {
546  LIB_PART* tmp = nullptr;
547  libSymbol.reset();
548 
549  // If the symbol is already in the internal library, map the symbol to it.
550  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
551 
552  if( ( it != m_libSymbols.end() ) )
553  {
554  if( aReporter )
555  {
556  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier "
557  "to '%s'. " ),
558  symbol->GetField( REFERENCE_FIELD )->GetText(),
559  symbol->GetField( VALUE_FIELD )->GetText(),
560  symbol->GetLibId().Format().wx_str() );
561  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
562  }
563 
564  // Internal library symbols are already flattened so just make a copy.
565  symbol->SetLibSymbol( new LIB_PART( *it->second ) );
566  continue;
567  }
568 
569  if( !symbol->GetLibId().IsValid() )
570  {
571  if( aReporter )
572  {
573  msg.Printf( _( "Schematic symbol reference '%s' library identifier is not "
574  "valid. Unable to link library symbol." ),
575  symbol->GetLibId().Format().wx_str() );
576  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
577  }
578 
579  continue;
580  }
581 
582  // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
583  // is not found in the table so check if the library still exists in the table
584  // before attempting to load the symbol.
585  if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
586  {
587  if( aReporter )
588  {
589  msg.Printf( _( "Symbol library '%s' not found and no fallback cache "
590  "library available. Unable to link library symbol." ),
591  symbol->GetLibId().GetLibNickname().wx_str() );
592  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
593  }
594 
595  continue;
596  }
597 
598  if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
599  {
600  try
601  {
602  tmp = libs->LoadSymbol( symbol->GetLibId() );
603  }
604  catch( const IO_ERROR& ioe )
605  {
606  if( aReporter )
607  {
608  msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
609  symbol->GetLibId().Format().wx_str() );
610  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
611  }
612  }
613  }
614 
615  if( !tmp && legacyLibs && legacyLibs->GetLibraryCount() )
616  {
617  PART_LIB& legacyCacheLib = legacyLibs->at( 0 );
618 
619  // It better be the cache library.
620  wxCHECK2( legacyCacheLib.IsCache(), continue );
621 
622  wxString id = symbol->GetLibId().Format();
623 
624  id.Replace( ':', '_' );
625 
626  if( aReporter )
627  {
628  msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
629  symbol->GetField( REFERENCE_FIELD )->GetText(),
630  symbol->GetField( VALUE_FIELD )->GetText(),
631  id );
632  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
633  }
634 
635  tmp = legacyCacheLib.FindPart( id );
636  }
637 
638  if( tmp )
639  {
640  // We want a full symbol not just the top level child symbol.
641  libSymbol = tmp->Flatten();
642  libSymbol->SetParent();
643 
644  m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
645  new LIB_PART( *libSymbol.get() ) } );
646 
647  if( aReporter )
648  {
649  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
650  symbol->GetField( REFERENCE_FIELD )->GetText(),
651  symbol->GetField( VALUE_FIELD )->GetText(),
652  symbol->GetLibId().Format().wx_str() );
653  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
654  }
655  }
656  else
657  {
658  if( aReporter )
659  {
660  msg.Printf( _( "No library symbol found for schematic symbol '%s %s'." ),
661  symbol->GetField( REFERENCE_FIELD )->GetText(),
662  symbol->GetField( VALUE_FIELD )->GetText() );
663  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
664  }
665  }
666 
667  symbol->SetLibSymbol( libSymbol.release() );
668  }
669 
670  // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
671  // item with the new bbox
672  for( auto symbol : symbols )
673  Append( symbol );
674 }
675 
676 
678 {
679  std::vector<SCH_COMPONENT*> symbols;
680 
681  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
682  symbols.push_back( static_cast<SCH_COMPONENT*>( item ) );
683 
684  for( SCH_COMPONENT* symbol : symbols )
685  {
686  // Changing the symbol may adjust the bbox of the symbol; remove and reinsert it afterwards.
687  m_rtree.remove( symbol );
688 
689  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
690 
691  LIB_PART* libSymbol = nullptr;
692 
693  if( it != m_libSymbols.end() )
694  libSymbol = new LIB_PART( *it->second );
695 
696  symbol->SetLibSymbol( libSymbol );
697 
698  m_rtree.insert( symbol );
699  }
700 }
701 
702 
703 void SCH_SCREEN::SwapSymbolLinks( const SCH_COMPONENT* aOriginalSymbol,
704  const SCH_COMPONENT* aNewSymbol )
705 {
706  wxCHECK( aOriginalSymbol && aNewSymbol /* && m_rtree.contains( aOriginalSymbol, true ) */,
707  /* void */ );
708 
709  if( aOriginalSymbol->GetSchSymbolLibraryName() == aNewSymbol->GetSchSymbolLibraryName() )
710  return;
711 }
712 
713 
714 void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
715 {
716  // Ensure links are up to date, even if a library was reloaded for some reason:
717  std::vector<SCH_ITEM*> junctions;
718  std::vector<SCH_ITEM*> bitmaps;
719  std::vector<SCH_ITEM*> other;
720 
721  for( SCH_ITEM* item : Items() )
722  {
723  if( item->IsMoving() || item->IsResized() )
724  continue;
725 
726  if( item->Type() == SCH_JUNCTION_T )
727  junctions.push_back( item );
728  else if( item->Type() == SCH_BITMAP_T )
729  bitmaps.push_back( item );
730  else
731  other.push_back( item );
732  }
733 
735  std::sort( other.begin(), other.end(),
736  []( const SCH_ITEM* a, const SCH_ITEM* b )
737  {
738  if( a->Type() == b->Type() )
739  return a->GetLayer() > b->GetLayer();
740 
741  return a->Type() > b->Type();
742  } );
743 
744  for( SCH_ITEM* item : bitmaps )
745  item->Print( aSettings, wxPoint( 0, 0 ) );
746 
747  for( SCH_ITEM* item : other )
748  item->Print( aSettings, wxPoint( 0, 0 ) );
749 
750  for( SCH_ITEM* item : junctions )
751  item->Print( aSettings, wxPoint( 0, 0 ) );
752 }
753 
754 
755 void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
756 {
757  // Ensure links are up to date, even if a library was reloaded for some reason:
758  std::vector< SCH_ITEM* > junctions;
759  std::vector< SCH_ITEM* > bitmaps;
760  std::vector< SCH_ITEM* > other;
761 
762  for( auto item : Items() )
763  {
764  if( item->IsMoving() || item->IsResized() )
765  continue;
766 
767  if( item->Type() == SCH_JUNCTION_T )
768  junctions.push_back( item );
769  else if( item->Type() == SCH_BITMAP_T )
770  bitmaps.push_back( item );
771  else
772  other.push_back( item );
773  }
774 
776  std::sort( other.begin(), other.end(),
777  []( const SCH_ITEM* a, const SCH_ITEM* b )
778  {
779  if( a->Type() == b->Type() )
780  return a->GetLayer() > b->GetLayer();
781 
782  return a->Type() > b->Type();
783  } );
784 
785  int defaultPenWidth = aPlotter->RenderSettings()->GetDefaultPenWidth();
786 
787  // Bitmaps are drawn first to ensure they are in the background
788  // This is particularly important for the wxPostscriptDC (used in *nix printers) as
789  // the bitmap PS command clears the screen
790  for( const SCH_ITEM* item : bitmaps )
791  {
792  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
793  item->Plot( aPlotter );
794  }
795 
796  for( const SCH_ITEM* item : other )
797  {
798  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
799  item->Plot( aPlotter );
800  }
801 
802  for( const SCH_ITEM* item : junctions )
803  {
804  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
805  item->Plot( aPlotter );
806  }
807 }
808 
809 
811 {
812  for( SCH_ITEM* item : Items() )
813  item->ClearTempFlags();
814 }
815 
816 
817 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aSymbol,
818  bool aEndPointOnly ) const
819 {
820  SCH_COMPONENT* candidate = NULL;
821  LIB_PIN* pin = NULL;
822 
823  for( SCH_ITEM* item : Items().Overlapping( SCH_COMPONENT_T, aPosition ) )
824  {
825  candidate = static_cast<SCH_COMPONENT*>( item );
826 
827  if( aEndPointOnly )
828  {
829  pin = NULL;
830 
831  if( !candidate->GetPartRef() )
832  continue;
833 
834  for( pin = candidate->GetPartRef()->GetNextPin(); pin;
835  pin = candidate->GetPartRef()->GetNextPin( pin ) )
836  {
837  // Skip items not used for this part.
838  if( candidate->GetUnit() && pin->GetUnit() &&
839  ( pin->GetUnit() != candidate->GetUnit() ) )
840  continue;
841 
842  if( candidate->GetConvert() && pin->GetConvert() &&
843  ( pin->GetConvert() != candidate->GetConvert() ) )
844  continue;
845 
846  if( candidate->GetPinPhysicalPosition( pin ) == aPosition )
847  break;
848  }
849 
850  if( pin )
851  break;
852  }
853  else
854  {
855  pin = (LIB_PIN*) candidate->GetDrawItem( aPosition, LIB_PIN_T );
856 
857  if( pin )
858  break;
859  }
860  }
861 
862  if( pin && aSymbol )
863  *aSymbol = candidate;
864 
865  return pin;
866 }
867 
868 
869 SCH_SHEET_PIN* SCH_SCREEN::GetSheetPin( const wxPoint& aPosition ) const
870 {
871  SCH_SHEET_PIN* sheetPin = nullptr;
872 
873  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
874  {
875  auto sheet = static_cast<SCH_SHEET*>( item );
876 
877  sheetPin = sheet->GetPin( aPosition );
878 
879  if( sheetPin )
880  break;
881  }
882 
883  return sheetPin;
884 }
885 
886 
887 size_t SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
888 {
889  size_t count = 0;
890 
891  for( const SCH_ITEM* item : Items() )
892  {
893  if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
894  count++;
895  }
896 
897  return count;
898 }
899 
900 
902 {
903 
904  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
905  {
906  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
907 
908  symbol->ClearAnnotation( aSheetPath );
909  }
910 }
911 
912 
914 {
915  if( GetClientSheetPaths().size() <= 1 ) // No need for alternate reference
916  return;
917 
918  for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
919  {
920  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
921 
922  // Add (when not existing) all sheet path entries
923  for( const SCH_SHEET_PATH& sheet : GetClientSheetPaths() )
924  symbol->AddSheetPathReferenceEntryIfMissing( sheet.Path() );
925  }
926 }
927 
928 
929 void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems ) const
930 {
931  static KICAD_T hierarchicalTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
932 
933  for( SCH_ITEM* item : Items() )
934  {
935  if( item->IsType( hierarchicalTypes ) )
936  aItems->push_back( item );
937  }
938 }
939 
940 
941 void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
942 {
943  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
944  aItems->push_back( item );
945 
946  std::sort( aItems->begin(), aItems->end(),
947  []( EDA_ITEM* a, EDA_ITEM* b ) -> bool
948  {
949  if( a->GetPosition().x == b->GetPosition().x )
950  return a->GetPosition().y < b->GetPosition().y;
951  else
952  return a->GetPosition().x < b->GetPosition().x;
953  } );
954 }
955 
956 
958  std::function<void( SCH_ITEM* )>* aChangedHandler ) const
959 {
960  std::vector<DANGLING_END_ITEM> endPoints;
961 
962  for( SCH_ITEM* item : Items() )
963  item->GetEndPoints( endPoints );
964 
965  for( SCH_ITEM* item : Items() )
966  {
967  if( item->UpdateDanglingState( endPoints, aPath ) )
968  {
969  if( aChangedHandler )
970  (*aChangedHandler)( item );
971  }
972  }
973 }
974 
975 
976 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
977  SCH_LINE_TEST_T aSearchType ) const
978 {
979  // an accuracy of 0 had problems with rounding errors; use at least 1
980  aAccuracy = std::max( aAccuracy, 1 );
981 
982  for( SCH_ITEM* item : Items() )
983  {
984  if( item->Type() != SCH_LINE_T )
985  continue;
986 
987  if( item->GetLayer() != aLayer )
988  continue;
989 
990  if( !item->HitTest( aPosition, aAccuracy ) )
991  continue;
992 
993  switch( aSearchType )
994  {
995  case ENTIRE_LENGTH_T:
996  return (SCH_LINE*) item;
997 
999  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1000  return (SCH_LINE*) item;
1001  break;
1002 
1003  case END_POINTS_ONLY_T:
1004  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1005  return (SCH_LINE*) item;
1006  }
1007  }
1008 
1009  return NULL;
1010 }
1011 
1012 
1013 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy ) const
1014 {
1015  for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1016  {
1017  switch( item->Type() )
1018  {
1019  case SCH_LABEL_T:
1020  case SCH_GLOBAL_LABEL_T:
1021  case SCH_HIER_LABEL_T:
1022  if( item->HitTest( aPosition, aAccuracy ) )
1023  return static_cast<SCH_TEXT*>( item );
1024 
1025  break;
1026 
1027  default:
1028  ;
1029  }
1030  }
1031 
1032  return NULL;
1033 }
1034 
1035 
1037 {
1038  wxCHECK( aLibSymbol, /* void */ );
1039 
1040  wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
1041 
1042  auto it = m_libSymbols.find( libSymbolName );
1043 
1044  if( it != m_libSymbols.end() )
1045  {
1046  delete it->second;
1047  m_libSymbols.erase( it );
1048  }
1049 
1050  m_libSymbols[libSymbolName] = aLibSymbol;
1051 }
1052 
1053 
1054 void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1055 {
1056  m_aliases.insert( aAlias );
1057 }
1058 
1059 
1060 #if defined(DEBUG)
1061 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1062 {
1063  // for now, make it look like XML, expand on this later.
1064  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1065 
1066  for( const SCH_ITEM* item : Items() )
1067  item->Show( nestLevel + 1, os );
1068 
1069  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1070 }
1071 #endif
1072 
1073 
1075 {
1076  m_index = 0;
1077  buildScreenList( aSheet );
1078 }
1079 
1080 
1082 {
1083 }
1084 
1085 
1087 {
1088  m_index = 0;
1089 
1090  if( m_screens.size() > 0 )
1091  return m_screens[0];
1092 
1093  return NULL;
1094 }
1095 
1096 
1098 {
1099  if( m_index < m_screens.size() )
1100  m_index++;
1101 
1102  return GetScreen( m_index );
1103 }
1104 
1105 
1106 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1107 {
1108  if( aIndex < m_screens.size() )
1109  return m_screens[ aIndex ];
1110 
1111  return NULL;
1112 }
1113 
1114 
1115 SCH_SHEET* SCH_SCREENS::GetSheet( unsigned int aIndex ) const
1116 {
1117  if( aIndex < m_sheets.size() )
1118  return m_sheets[ aIndex ];
1119 
1120  return NULL;
1121 }
1122 
1123 
1125 {
1126  if( aScreen == NULL )
1127  return;
1128 
1129  for( const SCH_SCREEN* screen : m_screens )
1130  {
1131  if( screen == aScreen )
1132  return;
1133  }
1134 
1135  m_screens.push_back( aScreen );
1136  m_sheets.push_back( aSheet );
1137 }
1138 
1139 
1141 {
1142  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1143  {
1144  SCH_SCREEN* screen = aSheet->GetScreen();
1145 
1146  addScreenToList( screen, aSheet );
1147 
1148  for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
1149  buildScreenList( static_cast<SCH_SHEET*>( item ) );
1150  }
1151 }
1152 
1153 
1155 {
1156  SCH_SCREEN* first = GetFirst();
1157 
1158  if( !first )
1159  return;
1160 
1161  SCHEMATIC* sch = first->Schematic();
1162 
1163  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" );
1164 
1165  // Clear the annotation for symbols inside new sheetpaths not already in aInitialSheetList
1166  SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths
1167  screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1168 
1169  // Search for new sheet paths, not existing in aInitialSheetPathList
1170  // and existing in sheetpathList
1171  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1172  {
1173  bool path_exists = false;
1174 
1175  for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1176  {
1177  if( existing_sheetpath.Path() == sheetpath.Path() )
1178  {
1179  path_exists = true;
1180  break;
1181  }
1182  }
1183 
1184  if( !path_exists )
1185  {
1186  // A new sheet path is found: clear the annotation corresponding to this new path:
1187  SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1188 
1189  // Clear annotation and create the AR for this path, if not exists,
1190  // when the screen is shared by sheet paths.
1191  // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1192  // reference default value and takes the latest displayed value
1193  curr_screen->EnsureAlternateReferencesExist();
1194  curr_screen->ClearAnnotation( &sheetpath );
1195  }
1196  }
1197 }
1198 
1199 
1201 {
1202  std::vector<SCH_ITEM*> items;
1203  int count = 0;
1204 
1205  auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1206  {
1207  return a->m_Uuid < b->m_Uuid;
1208  };
1209 
1210  std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1211 
1212  for( SCH_SCREEN* screen : m_screens )
1213  screen->GetHierarchicalItems( &items );
1214 
1215  if( items.size() < 2 )
1216  return 0;
1217 
1218  for( EDA_ITEM* item : items )
1219  {
1220  if( !unique_stamps.insert( item ).second )
1221  {
1222  // Reset to fully random UUID. This may lose reference, but better to be
1223  // deterministic about it rather than to have duplicate UUIDs with random
1224  // side-effects.
1225  const_cast<KIID&>( item->m_Uuid ) = KIID();
1226  count++;
1227  }
1228  }
1229 
1230  return count;
1231 }
1232 
1233 
1235 {
1236  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1237  {
1238  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1239  {
1240  if( item == aMarker )
1241  {
1242  screen->DeleteItem( item );
1243  return;
1244  }
1245  }
1246  }
1247 }
1248 
1249 
1250 void SCH_SCREENS::DeleteMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType, int aErrorCode,
1251  bool aIncludeExclusions )
1252 {
1253  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1254  {
1255  std::vector<SCH_ITEM*> markers;
1256 
1257  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1258  {
1259  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
1260  std::shared_ptr<RC_ITEM>rcItem = marker->GetRCItem();
1261 
1262  if( marker->GetMarkerType() == aMarkerType
1263  && ( aErrorCode == ERCE_UNSPECIFIED || rcItem->GetErrorCode() == aErrorCode )
1264  && ( !marker->IsExcluded() || aIncludeExclusions ) )
1265  {
1266  markers.push_back( item );
1267  }
1268  }
1269 
1270  for( SCH_ITEM* marker : markers )
1271  screen->DeleteItem( marker );
1272  }
1273 }
1274 
1275 
1277  bool aIncludeExclusions )
1278 {
1279  DeleteMarkers( aMarkerType, ERCE_UNSPECIFIED, aIncludeExclusions );
1280 }
1281 
1282 
1284 {
1285  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1286  screen->UpdateSymbolLinks( aReporter );
1287 
1288  SCH_SCREEN* first = GetFirst();
1289 
1290  if( !first )
1291  return;
1292 
1293  SCHEMATIC* sch = first->Schematic();
1294 
1295  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" );
1296 
1297  SCH_SHEET_LIST sheets = sch->GetSheets();
1298 
1299  // All of the library symbols have been replaced with copies so the connection graph
1300  // pointers are stale.
1301  if( sch->ConnectionGraph() )
1302  sch->ConnectionGraph()->Recalculate( sheets, true );
1303 }
1304 
1305 
1307 {
1308  SCH_SCREEN* screen;
1309  unsigned cnt = 0;
1310 
1311  for( screen = GetFirst(); screen; screen = GetNext() )
1312  {
1313  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1314  {
1315  cnt++;
1316  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
1317 
1318  if( !symbol->GetLibId().GetLibNickname().empty() )
1319  return false;
1320  }
1321  }
1322 
1323  return cnt != 0;
1324 }
1325 
1326 
1327 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1328 {
1329  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1330  {
1331  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1332  {
1333  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
1334  const UTF8& nickname = symbol->GetLibId().GetLibNickname();
1335 
1336  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1337  aLibNicknames.Add( nickname );
1338  }
1339  }
1340 
1341  return aLibNicknames.GetCount();
1342 }
1343 
1344 
1345 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1346 {
1347  SCH_SCREEN* screen;
1348  int cnt = 0;
1349 
1350  for( screen = GetFirst(); screen; screen = GetNext() )
1351  {
1352  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
1353  {
1354  auto symbol = static_cast<SCH_COMPONENT*>( item );
1355 
1356  if( symbol->GetLibId().GetLibNickname() != aFrom )
1357  continue;
1358 
1359  LIB_ID id = symbol->GetLibId();
1360  id.SetLibNickname( aTo );
1361  symbol->SetLibId( id );
1362  cnt++;
1363  }
1364  }
1365 
1366  return cnt;
1367 }
1368 
1369 
1370 bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
1371 {
1372  for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1373  {
1374  if( screen->GetFileName() == aSchematicFileName )
1375  return true;
1376  }
1377 
1378  return false;
1379 }
1380 
1381 
1382 bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
1383 {
1384  wxString lhsLower;
1385  wxString rhsLower;
1386  wxFileName lhs;
1387  wxFileName rhs = aSchematicFileName;
1388 
1389  wxCHECK( rhs.IsAbsolute(), false );
1390 
1391  for( const SCH_SCREEN* screen : m_screens )
1392  {
1393  lhs = screen->GetFileName();
1394 
1395  if( lhs.GetPath() != rhs.GetPath() )
1396  continue;
1397 
1398  lhsLower = lhs.GetFullName().Lower();
1399  rhsLower = rhs.GetFullName().Lower();
1400 
1401  if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
1402  return true;
1403  }
1404 
1405  return false;
1406 }
1407 
1408 
1410 {
1411  SCH_SCREEN* first = GetFirst();
1412 
1413  if( !first )
1414  return;
1415 
1416  SCHEMATIC* sch = first->Schematic();
1417 
1418  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" );
1419 
1420  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1421  curr_screen->GetClientSheetPaths().clear();
1422 
1423  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1424  {
1425  SCH_SCREEN* used_screen = sheetpath.LastScreen();
1426 
1427  // SEarch for the used_screen in list and add this unique sheet path:
1428  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1429  {
1430  if( used_screen == curr_screen )
1431  {
1432  curr_screen->GetClientSheetPaths().push_back( sheetpath );
1433  break;
1434  }
1435  }
1436  }
1437 }
Field Reference of part, i.e. "IC21".
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
void insert(SCH_ITEM *aItem)
Insert an item into the tree.
Definition: sch_rtree.h:60
void Plot(PLOTTER *aPlotter) const
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:755
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:244
SCH_SCREEN * GetNext()
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void DeleteMarkers(enum MARKER_BASE::TYPEMARKER aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
LIB_ID GetLibId() const override
Definition: lib_symbol.h:131
wxPoint GetStartPoint() const
Definition: sch_line.h:90
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Holds all the data relating to one schematic.
Definition: schematic.h:59
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:129
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
Definition: sch_screen.cpp:941
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:457
void clearLibSymbols()
Definition: sch_screen.cpp:97
double m_LastZoomLevel
last value for the zoom level, useful in Eeschema when changing the current displayed sheet to reuse ...
Definition: sch_screen.h:473
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:238
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
Definition: reporter.h:93
void addScreenToList(SCH_SCREEN *aScreen, SCH_SHEET *aSheet)
void sort()
Definition: multivector.h:247
int m_refCount
Definition: sch_screen.h:484
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:957
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:126
int GetLibraryCount()
void Clear()
Definition: title_block.h:113
LIB_ITEM * GetDrawItem(const wxPoint &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr)
Updates the connection graph for the given list of sheets.
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
Definition: sch_screen.cpp:913
void SetSchSymbolLibraryName(const wxString &aName)
The name of the symbol in the schematic library symbol list.
Definition: sch_symbol.h:160
virtual wxPoint GetPosition() const
Definition: eda_item.h:302
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_COMPONENT **aSymbol=NULL, bool aEndPointOnly=false) const
Test the screen for a component pin item at aPosition.
Definition: sch_screen.cpp:817
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
Definition: sch_screen.h:501
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:166
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
Definition: sch_line.cpp:780
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:199
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:47
SCH_SCREEN(EDA_ITEM *aParent=nullptr)
Definition: sch_screen.cpp:64
unsigned int m_index
Definition: sch_screen.h:678
Definition: kiid.h:44
bool HasItems(KICAD_T aItemType) const
Definition: sch_screen.cpp:120
int GetUnit() const
Definition: sch_symbol.h:195
void UpdateLocalLibSymbolLinks()
Initialize the LIB_PART reference for each SCH_COMPONENT found in this schematic with the local proje...
Definition: sch_screen.cpp:677
int GetAngleFrom(const wxPoint &aPoint) const
Definition: sch_line.cpp:414
std::vector< SCH_SHEET * > m_sheets
Definition: sch_screen.h:677
TITLE_BLOCK m_titles
Definition: sch_screen.h:497
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition: sch_rtree.h:75
PAGE_INFO m_paper
Definition: sch_screen.h:496
Field Value of part, i.e. "3.3K".
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:394
bool m_Center
Center on screen.
Definition: base_screen.h:100
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:282
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:469
SCH_LINE_TEST_T
Definition: sch_screen.h:70
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:40
iterator end()
Definition: sch_rtree.h:250
SCH_SHEET_PIN * GetSheetPin(const wxPoint &aPosition) const
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:869
int m_pageCount
The number of BASE_SCREEN objects in this design.
Definition: base_screen.h:115
EE_RTREE m_rtree
Definition: sch_screen.h:499
void DeleteAllMarkers(enum MARKER_BASE::TYPEMARKER aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
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:313
Define a library symbol object.
Definition: lib_symbol.h:93
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
EDA_ITEM * GetParent() const
Definition: eda_item.h:165
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:92
bool IsExcluded() const
Definition: marker_base.h:94
bool IsEndPoint(const wxPoint &aPoint) const
Definition: sch_line.h:80
#define STRUCT_DELETED
flag indication structures to be erased
Definition: eda_item.h:116
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_PART > & GetPartRef()
Definition: sch_symbol.h:164
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:334
void DeleteMarker(SCH_MARKER *aMarker)
Delete a specific marker.
LIB_PART * FindPart(const wxString &aName) const
Find LIB_PART by aName.
iterator end()
Definition: sch_rtree.h:210
UTF8 Format() const
Definition: lib_id.cpp:233
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:218
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:310
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
const KIID m_Uuid
Definition: eda_item.h:525
bool contains(const SCH_ITEM *aItem, bool aRobust=false) const
Determine if a given item exists in the tree.
Definition: sch_rtree.h:118
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:272
A collection of PART_LIB objects.
size_t CountConnectedItems(const wxPoint &aPos, bool aTestJunctions) const
Definition: sch_screen.cpp:887
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:112
Base plotter engine class.
Definition: plotter.h:121
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:522
SCH_SHEET & Root() const
Definition: schematic.h:92
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:155
iterator begin()
Definition: sch_rtree.h:205
see class PGM_BASE
void Print(const RENDER_SETTINGS *aSettings)
Print all the items in the screen to aDC.
Definition: sch_screen.cpp:714
void AddLibSymbol(LIB_PART *aLibSymbol)
Add aLibSymbol to the the library symbol map.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add 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
bool m_zoomInitialized
Definition: sch_screen.h:504
SCH_LINE * GetLine(const wxPoint &aPosition, int aAccuracy=0, int aLayer=LAYER_NOTES, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Return a line item located at aPosition.
Definition: sch_screen.cpp:976
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:676
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:128
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:92
iterator begin()
Definition: sch_rtree.h:245
SCH_LINE * GetWire(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:388
#define _(s)
Definition: 3d_actions.cpp:33
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:88
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:508
EE_RTREE & Items()
Definition: sch_screen.h:103
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:178
Handle the component boundary box.
Definition: eda_rect.h:42
SCH_SHEET * GetSheet(unsigned int aIndex) const
Schematic symbol object.
Definition: sch_symbol.h:78
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsJunctionNeeded(const wxPoint &aPosition, bool aNew=false) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:374
SCH_TEXT * GetLabel(const wxPoint &aPosition, int aAccuracy=0) const
Return a label item located at aPosition.
int GetDefaultPenWidth() const
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:901
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:2976
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition: sch_screen.h:159
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
int GetConvert() const
Definition: sch_symbol.h:223
SCH_SCREEN * GetFirst()
SCH_SCREEN * GetScreen(unsigned int aIndex) const
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:166
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:810
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:237
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:59
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_PART reference for each SCH_COMPONENT found in the full schematic.
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath)
Clear exiting symbol annotation.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:147
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 nicknames into aLibNicknames.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
bool IsCache() const
void clear()
Remove all items from the RTree.
Definition: sch_rtree.h:104
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
void GetHierarchicalItems(std::vector< SCH_ITEM * > *aItems) const
Add all schematic sheet and component objects in the screen to aItems.
Definition: sch_screen.cpp:929
bool IsConnected(const wxPoint &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:122
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:100
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:549
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:363
void SwapSymbolLinks(const SCH_COMPONENT *aOriginalSymbol, const SCH_COMPONENT *aNewSymbol)
Definition: sch_screen.cpp:703
void IncRefCount()
Definition: sch_screen.cpp:106
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
bool empty() const
Definition: utf8.h:103
bool CheckIfOnDrawList(const SCH_ITEM *aItem) const
Definition: sch_screen.cpp:307
virtual wxString GetClass() const override
Return the class name.
Definition: sch_screen.h:120
std::map< wxString, LIB_PART * > m_libSymbols
Library symbols required for this schematic.
Definition: sch_screen.h:511
int m_virtualPageNumber
An integer based page number used for printing a range of pages.
Definition: base_screen.h:123
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
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:329
wxPoint GetEndPoint() const
Definition: sch_line.h:93