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