KiCad PCB EDA Suite
sch_screen.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
32 #include <fctsys.h>
33 #include <gr_basic.h>
34 #include <common.h>
35 #include <kicad_string.h>
36 #include <eeschema_id.h>
37 #include <pgm_base.h>
38 #include <kiway.h>
39 #include <class_drawpanel.h>
40 #include <sch_item_struct.h>
41 #include <schframe.h>
42 #include <class_plotter.h>
43 
44 #include <netlist.h>
45 #include <class_netlist_object.h>
46 #include <class_library.h>
47 #include <sch_junction.h>
48 #include <sch_bus_entry.h>
49 #include <sch_line.h>
50 #include <sch_marker.h>
51 #include <sch_no_connect.h>
52 #include <sch_sheet.h>
53 #include <sch_component.h>
54 #include <sch_text.h>
55 #include <lib_pin.h>
56 #include <symbol_lib_table.h>
57 
58 
59 #define EESCHEMA_FILE_STAMP "EESchema"
60 
61 /* Default zoom values. Limited to these values to keep a decent size
62  * to menus
63  */
64 static double SchematicZoomList[] =
65 {
66  0.5, 0.7, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 11.0,
67  13.0, 16.0, 20.0, 26.0, 32.0, 48.0, 64.0, 80.0, 128.0
68 };
69 
70 /* Default grid sizes for the schematic editor.
71  * Do NOT add others values (mainly grid values in mm), because they
72  * can break the schematic: Because wires and pins are considered as
73  * connected when the are to the same coordinate we cannot mix
74  * coordinates in mils (internal units) and mm (that cannot exactly
75  * converted in mils in many cases). In fact schematic must only use
76  * 50 and 25 mils to place labels, wires and components others values
77  * are useful only for graphic items (mainly in library editor) so use
78  * integer values in mils only. The 100 mil grid is added to help
79  * conform to the KiCad Library Convention. Which states: "Using a
80  * 100mil grid, pin ends and origin must lie on grid nodes IEC-60617"
81 */
83  { ID_POPUP_GRID_LEVEL_100, wxRealPoint( 100, 100 ) },
84  { ID_POPUP_GRID_LEVEL_50, wxRealPoint( 50, 50 ) },
85  { ID_POPUP_GRID_LEVEL_25, wxRealPoint( 25, 25 ) },
86  { ID_POPUP_GRID_LEVEL_10, wxRealPoint( 10, 10 ) },
87  { ID_POPUP_GRID_LEVEL_5, wxRealPoint( 5, 5 ) },
88  { ID_POPUP_GRID_LEVEL_2, wxRealPoint( 2, 2 ) },
89  { ID_POPUP_GRID_LEVEL_1, wxRealPoint( 1, 1 ) },
90 };
91 
92 
95  KIWAY_HOLDER( aKiway ),
96  m_paper( wxT( "A4" ) )
97 {
99 
100  SetZoom( 32 );
101 
102  for( unsigned i = 0; i < DIM( SchematicZoomList ); i++ )
103  m_ZoomList.push_back( SchematicZoomList[i] );
104 
105  for( unsigned i = 0; i < DIM( SchematicGridList ); i++ )
106  AddGrid( SchematicGridList[i] );
107 
108  SetGrid( wxRealPoint( 50, 50 ) ); // Default grid size.
109  m_refCount = 0;
110 
111  // Suitable for schematic only. For libedit and viewlib, must be set to true
112  m_Center = false;
113 
114  InitDataPoints( m_paper.GetSizeIU() );
115 }
116 
117 
119 {
121  FreeDrawList();
122 }
123 
124 
126 {
127  m_refCount++;
128 }
129 
130 
132 {
133  wxCHECK_RET( m_refCount != 0,
134  wxT( "Screen reference count already zero. Bad programmer!" ) );
135  m_refCount--;
136 }
137 
138 
140 {
141  wxCHECK_RET( aScreen, "Invalid screen object." );
142 
143  // No need to decend the hierarchy. Once the top level screen is copied, all of it's
144  // children are copied as well.
145  m_drawList.Append( aScreen->m_drawList );
146 
147  // This screen owns the objects now. This prevents the object from being delete when
148  // aSheet is deleted.
149  aScreen->m_drawList.SetOwnership( false );
150 }
151 
152 
154 {
155  FreeDrawList();
156 
157  // Clear the project settings
159 
160  m_titles.Clear();
161 }
162 
163 
165 {
167 }
168 
169 
171 {
172  m_drawList.Remove( aItem );
173 }
174 
175 
177 {
178  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
179 
180  SetModify();
181 
182  if( aItem->Type() == SCH_SHEET_PIN_T )
183  {
184  // This structure is attached to a sheet, get the parent sheet object.
185  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
186  SCH_SHEET* sheet = sheetPin->GetParent();
187  wxCHECK_RET( sheet,
188  wxT( "Sheet label parent not properly set, bad programmer!" ) );
189  sheet->RemovePin( sheetPin );
190  return;
191  }
192  else
193  {
194  delete m_drawList.Remove( aItem );
195  }
196 }
197 
198 
200 {
201  SCH_ITEM* itemList = m_drawList.begin();
202 
203  while( itemList )
204  {
205  if( itemList == aItem )
206  return true;
207 
208  itemList = itemList->Next();
209  }
210 
211  return false;
212 }
213 
214 
215 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
216 {
217  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
218  {
219  if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) )
220  return item;
221 
222  if( (aType == SCH_FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
223  {
224  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
225 
226  for( int i = REFERENCE; i < component->GetFieldCount(); i++ )
227  {
228  SCH_FIELD* field = component->GetField( i );
229 
230  if( field->HitTest( aPosition, aAccuracy ) )
231  return (SCH_ITEM*) field;
232  }
233  }
234  else if( (aType == SCH_SHEET_PIN_T) && (item->Type() == SCH_SHEET_T) )
235  {
236  SCH_SHEET* sheet = (SCH_SHEET*)item;
237 
238  SCH_SHEET_PIN* label = sheet->GetPin( aPosition );
239 
240  if( label )
241  return (SCH_ITEM*) label;
242  }
243  else if( (item->Type() == aType) && item->HitTest( aPosition, aAccuracy ) )
244  {
245  return item;
246  }
247  }
248 
249  return NULL;
250 }
251 
252 
253 void SCH_SCREEN::ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy )
254 {
255  SCH_ITEM* item;
256  SCH_ITEM* next_item;
257 
258  for( item = m_drawList.begin(); item; item = next_item )
259  {
260  next_item = item->Next();
261 
262  switch( item->Type() )
263  {
264  case SCH_JUNCTION_T:
265  case SCH_LINE_T:
266  m_drawList.Remove( item );
267  aList.Append( item );
268 
269  if( aCreateCopy )
270  m_drawList.Insert( (SCH_ITEM*) item->Clone(), next_item );
271 
272  break;
273 
274  default:
275  break;
276  }
277  }
278 }
279 
280 
282 {
283  SCH_ITEM* item;
284  SCH_ITEM* next_item;
285 
286  for( item = m_drawList.begin(); item; item = next_item )
287  {
288  next_item = item->Next();
289 
290  switch( item->Type() )
291  {
292  case SCH_JUNCTION_T:
293  case SCH_LINE_T:
294  Remove( item );
295  delete item;
296  break;
297 
298  default:
299  break;
300  }
301  }
302 
303  m_drawList.Append( aWireList );
304 }
305 
306 
308 {
309  wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T),
310  wxT( "Invalid object pointer." ) );
311 
312  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
313  {
314  if( item->GetFlags() & CANDIDATE )
315  continue;
316 
317  if( item->Type() == SCH_JUNCTION_T )
318  {
319  SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
320 
321  if( aSegment->IsEndPoint( junction->GetPosition() ) )
322  item->SetFlags( CANDIDATE );
323 
324  continue;
325  }
326 
327  if( item->Type() != SCH_LINE_T )
328  continue;
329 
330  SCH_LINE* segment = (SCH_LINE*) item;
331 
332  if( aSegment->IsEndPoint( segment->GetStartPoint() )
333  && !GetPin( segment->GetStartPoint(), NULL, true ) )
334  {
335  item->SetFlags( CANDIDATE );
336  MarkConnections( segment );
337  }
338 
339  if( aSegment->IsEndPoint( segment->GetEndPoint() )
340  && !GetPin( segment->GetEndPoint(), NULL, true ) )
341  {
342  item->SetFlags( CANDIDATE );
343  MarkConnections( segment );
344  }
345  }
346 }
347 
348 
349 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition )
350 {
351  if( GetItem( aPosition, 0, SCH_JUNCTION_T ) )
352  return false;
353 
354  if( GetWire( aPosition, 0, EXCLUDE_END_POINTS_T ) )
355  {
356  if( GetWire( aPosition, 0, END_POINTS_ONLY_T ) )
357  return true;
358 
359  if( GetPin( aPosition, NULL, true ) )
360  return true;
361  }
362 
363  return false;
364 }
365 
366 
367 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
368 {
369  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
370  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
371 
372  SCH_SHEET_PIN* label;
373  SCH_TEXT* text;
374 
375  switch( aLayer )
376  {
377  case LAYER_BUS:
378 
379  if( GetBus( aPosition ) )
380  return true;
381 
382  label = GetSheetLabel( aPosition );
383 
384  if( label && IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
385  return true;
386 
387  text = GetLabel( aPosition );
388 
389  if( text && IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
390  && (text->Type() != SCH_LABEL_T) )
391  return true;
392 
393  break;
394 
395  case LAYER_NOTES:
396 
397  if( GetLine( aPosition ) )
398  return true;
399 
400  break;
401 
402  case LAYER_WIRE:
404  return true;
405 
406  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_BUS_ENTRY_T) )
407  return true;
408 
409  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_JUNCTION_T ) )
410  return true;
411 
412  if( GetPin( aPosition, NULL, true ) )
413  return true;
414 
415  if( GetWire( aPosition ) )
416  return true;
417 
418  text = GetLabel( aPosition );
419 
420  if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
421  return true;
422 
423  label = GetSheetLabel( aPosition );
424 
425  if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->GetText() ) )
426  return true;
427 
428  break;
429 
430  default:
431  break;
432  }
433 
434  return false;
435 }
436 
437 
439 {
440  bool modified = false;
441 
442  for( SCH_ITEM* item = m_drawList.begin() ; item; item = item->Next() )
443  {
444  if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
445  continue;
446 
447  bool restart;
448 
449  for( SCH_ITEM* testItem = item->Next(); testItem; testItem = restart ? m_drawList.begin() : testItem->Next() )
450  {
451  restart = false;
452 
453  if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
454  {
455  SCH_LINE* line = (SCH_LINE*) item;
456 
457  if( line->MergeOverlap( (SCH_LINE*) testItem ) )
458  {
459  // Keep the current flags, because the deleted segment can be flagged.
460  item->SetFlags( testItem->GetFlags() );
461  DeleteItem( testItem );
462  restart = true;
463  modified = true;
464  }
465  }
466  else if ( ( ( item->Type() == SCH_JUNCTION_T )
467  && ( testItem->Type() == SCH_JUNCTION_T ) ) && ( testItem != item ) )
468  {
469  if ( testItem->HitTest( item->GetPosition() ) )
470  {
471  // Keep the current flags, because the deleted segment can be flagged.
472  item->SetFlags( testItem->GetFlags() );
473  DeleteItem( testItem );
474  restart = true;
475  modified = true;
476  }
477  }
478  }
479  }
480 
482 
483  return modified;
484 }
485 
486 
487 void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
488 {
489  // Initialize or reinitialize the pointer to the LIB_PART for each component
490  // found in m_drawList, but only if needed (change in lib or schematic)
491  // therefore the calculation time is usually very low.
492 
493  if( m_drawList.GetCount() )
494  {
495  SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
496  int mod_hash = libs->GetModifyHash();
497 
498  // Must we resolve?
499  if( (m_modification_sync != mod_hash) || aForce )
500  {
502 
504 
505  SCH_COMPONENT::ResolveAll( c, *libs, Prj().SchLibs()->GetCacheLibrary() );
506 
507  m_modification_sync = mod_hash; // note the last mod_hash
508  }
509  }
510 }
511 
512 
513 void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode, COLOR4D aColor )
514 {
515  /* note: SCH_SCREEN::Draw is useful only for schematic.
516  * library editor and library viewer do not use m_drawList, and therefore
517  * their SCH_SCREEN::Draw() draws nothing
518  */
519  std::vector< SCH_ITEM* > junctions;
520 
521  // Ensure links are up to date, even if a library was reloaded for some reason:
523 
524  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
525  {
526  if( item->IsMoving() || item->IsResized() )
527  continue;
528 
529  if( item->Type() == SCH_JUNCTION_T )
530  junctions.push_back( item );
531  else
532  // uncomment line below when there is a virtual EDA_ITEM::GetBoundingBox()
533  // if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
534  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
535  }
536 
537  for( auto item : junctions )
538  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
539 }
540 
541 
542 void SCH_SCREEN::Plot( PLOTTER* aPlotter )
543 {
544  // Ensure links are up to date, even if a library was reloaded for some reason:
546 
547  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
548  {
549  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
550  item->Plot( aPlotter );
551  }
552 }
553 
554 
556 {
557  if( aItemCount == 0 )
558  return;
559 
560  for( auto& command : aList.m_CommandsList )
561  {
562  command->ClearListAndDeleteItems();
563  delete command;
564  }
565 
566  aList.m_CommandsList.clear();
567 }
568 
569 
571 {
572  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
573  item->ClearFlags();
574 }
575 
576 
577 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent,
578  bool aEndPointOnly ) const
579 {
580  SCH_ITEM* item;
581  SCH_COMPONENT* component = NULL;
582  LIB_PIN* pin = NULL;
583 
584  for( item = m_drawList.begin(); item; item = item->Next() )
585  {
586  if( item->Type() != SCH_COMPONENT_T )
587  continue;
588 
589  component = (SCH_COMPONENT*) item;
590 
591  if( aEndPointOnly )
592  {
593  pin = NULL;
594 
595  auto part = component->GetPartRef().lock();
596 
597  if( !part )
598  continue;
599 
600  for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
601  {
602  // Skip items not used for this part.
603  if( component->GetUnit() && pin->GetUnit() &&
604  ( pin->GetUnit() != component->GetUnit() ) )
605  continue;
606 
607  if( component->GetConvert() && pin->GetConvert() &&
608  ( pin->GetConvert() != component->GetConvert() ) )
609  continue;
610 
611  if(component->GetPinPhysicalPosition( pin ) == aPosition )
612  break;
613  }
614  if( pin )
615  break;
616  }
617  else
618  {
619  pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
620 
621  if( pin )
622  break;
623  }
624  }
625 
626  if( pin && aComponent )
627  *aComponent = component;
628 
629  return pin;
630 }
631 
632 
633 SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName )
634 {
635  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
636  {
637  if( item->Type() != SCH_SHEET_T )
638  continue;
639 
640  SCH_SHEET* sheet = (SCH_SHEET*) item;
641 
642  if( aName.CmpNoCase( sheet->GetName() ) == 0 )
643  return sheet;
644  }
645 
646  return NULL;
647 }
648 
649 
651 {
652  SCH_SHEET_PIN* sheetPin = NULL;
653 
654  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
655  {
656  if( item->Type() != SCH_SHEET_T )
657  continue;
658 
659  SCH_SHEET* sheet = (SCH_SHEET*) item;
660  sheetPin = sheet->GetPin( aPosition );
661 
662  if( sheetPin )
663  break;
664  }
665 
666  return sheetPin;
667 }
668 
669 
670 int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
671 {
672  SCH_ITEM* item;
673  int count = 0;
674 
675  for( item = m_drawList.begin(); item; item = item->Next() )
676  {
677  if( item->Type() == SCH_JUNCTION_T && !aTestJunctions )
678  continue;
679 
680  if( item->IsConnected( aPos ) )
681  count++;
682  }
683 
684  return count;
685 }
686 
687 
689 {
690  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
691  {
692  if( item->Type() == SCH_COMPONENT_T )
693  {
694  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
695 
696  component->ClearAnnotation( aSheetPath );
697 
698  // Clear the modified component flag set by component->ClearAnnotation
699  // because we do not use it here and we should not leave this flag set,
700  // when an edition is finished:
701  component->ClearFlags();
702  }
703  }
704 }
705 
706 
708 {
709  SCH_ITEM* item = m_drawList.begin();
710 
711  while( item )
712  {
713  if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
714  aItems.push_back( item );
715 
716  item = item->Next();
717  }
718 }
719 
720 
722 {
723  auto addConnections = [ this ]( SCH_ITEM* item ) -> void
724  {
725  std::vector< wxPoint > connections;
726  item->GetConnectionPoints( connections );
727  for( auto conn : connections )
728  addConnectedItemsToBlock( conn );
729  };
730 
731  PICKED_ITEMS_LIST* pickedlist = &m_BlockLocate.GetItems();
732 
733  if( pickedlist->GetCount() == 0 )
734  return;
735 
737 
738  for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
739  {
740  SCH_ITEM* item = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
741  item->SetFlags( SELECTED );
742  }
743 
744  if( !m_BlockLocate.IsDragging() )
745  return;
746 
747  // Select all the items in the screen connected to the items in the block.
748  // be sure end lines that are on the block limits are seen inside this block
749  m_BlockLocate.Inflate( 1 );
750  unsigned last_select_id = pickedlist->GetCount();
751 
752  for( unsigned ii = 0; ii < last_select_id; ii++ )
753  {
754  SCH_ITEM* item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
755  item->SetFlags( IS_DRAGGED );
756 
757  if( item->Type() == SCH_LINE_T )
758  {
760 
761  if( !item->IsSelected() )
762  { // This is a special case:
763  // this selected wire has no ends in block.
764  // But it was selected (because it intersects the selecting area),
765  // so we must keep it selected and select items connected to it
766  // Note: an other option could be: remove it from drag list
767  item->SetFlags( SELECTED | SKIP_STRUCT );
768  addConnections( item );
769  }
770 
771  pickedlist->SetPickerFlags( item->GetFlags(), ii );
772  }
773  else if( item->IsConnectable() )
774  {
775  addConnections( item );
776  }
777  }
778 
779  // Select the items that are connected to a component that was added
780  // to our selection list in the last step.
781  for( unsigned ii = last_select_id; ii < pickedlist->GetCount(); ii++ )
782  {
783  SCH_ITEM* item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
784 
785  if( item->Type() == SCH_COMPONENT_T )
786  {
787  item->SetFlags( IS_DRAGGED );
788  addConnections( item );
789  }
790  }
791 
792  m_BlockLocate.Inflate( -1 );
793 }
794 
795 
797 {
798  SCH_ITEM* item;
799  ITEM_PICKER picker;
800 
801  for( item = m_drawList.begin(); item; item = item->Next() )
802  {
803  bool addinlist = true;
804  picker.SetItem( item );
805 
806  if( !item->IsConnectable() || !item->IsConnected( position )
807  || (item->GetFlags() & SKIP_STRUCT) )
808  continue;
809 
810  if( item->IsSelected() && item->Type() != SCH_LINE_T )
811  continue;
812 
813  // A line having 2 ends, it can be tested twice: one time per end
814  if( item->Type() == SCH_LINE_T )
815  {
816  if( ! item->IsSelected() ) // First time this line is tested
817  item->SetFlags( SELECTED | STARTPOINT | ENDPOINT );
818  else // second time (or more) this line is tested
819  addinlist = false;
820 
821  SCH_LINE* line = (SCH_LINE*) item;
822 
823  if( line->GetStartPoint() == position )
824  item->ClearFlags( STARTPOINT );
825  else if( line->GetEndPoint() == position )
826  item->ClearFlags( ENDPOINT );
827  }
828  else
829  item->SetFlags( SELECTED );
830 
831  if( addinlist )
832  {
833  picker.SetFlags( item->GetFlags() );
834  m_BlockLocate.GetItems().PushItem( picker );
835  }
836  }
837 }
838 
839 
841 {
842  ITEM_PICKER picker;
843  EDA_RECT area;
844  unsigned count;
845 
847  area.SetSize( m_BlockLocate.GetSize() );
848  area.Normalize();
849 
850  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
851  {
852  // An item is picked if its bounding box intersects the reference area.
853  if( item->HitTest( area ) )
854  {
855  picker.SetItem( item );
856  m_BlockLocate.PushItem( picker );
857  }
858  }
859 
860  // if the block is composed of one item,
861  // select it as the current item
862  count = m_BlockLocate.GetCount();
863  if( count == 1 )
864  {
866  }
867  else
868  {
869  SetCurItem( NULL );
870  }
871 
872  return count;
873 }
874 
875 
877 {
878  SCH_ITEM* item;
879  std::vector< DANGLING_END_ITEM > endPoints;
880  bool hasStateChanged = false;
881 
882  for( item = m_drawList.begin(); item; item = item->Next() )
883  item->GetEndPoints( endPoints );
884 
885  for( item = m_drawList.begin(); item; item = item->Next() )
886  {
887  if( item->IsDanglingStateChanged( endPoints ) )
888  {
889  hasStateChanged = true;
890  }
891  }
892 
893  return hasStateChanged;
894 }
895 
896 
897 bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
898 {
899  SCH_LINE* segment;
900  SCH_LINE* newSegment;
901  bool brokenSegments = false;
902 
903  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
904  {
905  if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
906  continue;
907 
908  segment = (SCH_LINE*) item;
909 
910  if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
911  continue;
912 
913  // Break the segment at aPoint and create a new segment.
914  newSegment = new SCH_LINE( *segment );
915  newSegment->SetStartPoint( aPoint );
916  segment->SetEndPoint( aPoint );
917  m_drawList.Insert( newSegment, segment->Next() );
918  item = newSegment;
919  brokenSegments = true;
920  }
921 
922  return brokenSegments;
923 }
924 
925 
927 {
928  bool brokenSegments = false;
929 
930  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
931  {
932  if( item->Type() == SCH_JUNCTION_T )
933  {
934  SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
935 
936  if( BreakSegment( junction->GetPosition() ) )
937  brokenSegments = true;
938  }
939  else
940  {
941  SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
942  if( busEntry )
943  {
944  if( BreakSegment( busEntry->GetPosition() )
945  || BreakSegment( busEntry->m_End() ) )
946  brokenSegments = true;
947  }
948  }
949  }
950 
951  return brokenSegments;
952 }
953 
954 
955 int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList )
956 {
957  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
958  {
959  if( item->Type() == SCH_LINE_T && item->HitTest( aPosition )
960  && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
961  {
962  aList.push_back( item );
963  }
964  else if( item->Type() == SCH_JUNCTION_T && item->HitTest( aPosition ) )
965  {
966  aList.push_back( item );
967  }
968  }
969 
970  return (int) aList.size();
971 }
972 
973 
975 {
976  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
977  {
978  if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition )
979  && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
980  {
981  return (SCH_LINE*) item;
982  }
983  }
984 
985  return NULL;
986 }
987 
988 
989 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
990  SCH_LINE_TEST_T aSearchType )
991 {
992  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
993  {
994  if( item->Type() != SCH_LINE_T )
995  continue;
996 
997  if( item->GetLayer() != aLayer )
998  continue;
999 
1000  if( !item->HitTest( aPosition, aAccuracy ) )
1001  continue;
1002 
1003  switch( aSearchType )
1004  {
1005  case ENTIRE_LENGTH_T:
1006  return (SCH_LINE*) item;
1007 
1008  case EXCLUDE_END_POINTS_T:
1009  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1010  return (SCH_LINE*) item;
1011  break;
1012 
1013  case END_POINTS_ONLY_T:
1014  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1015  return (SCH_LINE*) item;
1016  }
1017  }
1018 
1019  return NULL;
1020 }
1021 
1022 
1023 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
1024 {
1025  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1026  {
1027  switch( item->Type() )
1028  {
1029  case SCH_LABEL_T:
1030  case SCH_GLOBAL_LABEL_T:
1032  if( item->HitTest( aPosition, aAccuracy ) )
1033  return (SCH_TEXT*) item;
1034 
1035  default:
1036  ;
1037  }
1038  }
1039 
1040  return NULL;
1041 }
1042 
1043 
1044 bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
1045  const wxString& aFootPrint, bool aSetVisible )
1046 {
1047  SCH_COMPONENT* component;
1048  bool found = false;
1049 
1050  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1051  {
1052  if( item->Type() != SCH_COMPONENT_T )
1053  continue;
1054 
1055  component = (SCH_COMPONENT*) item;
1056 
1057  if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
1058  {
1059  // Found: Init Footprint Field
1060 
1061  /* Give a reasonable value to the field position and
1062  * orientation, if the text is empty at position 0, because
1063  * it is probably not yet initialized
1064  */
1065  SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
1066  if( fpfield->GetText().IsEmpty()
1067  && ( fpfield->GetTextPos() == component->GetPosition() ) )
1068  {
1069  fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
1070  fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
1071  fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
1072 
1073  if( fpfield->GetTextAngle() == 0.0 )
1074  fpfield->Offset( wxPoint( 0, 100 ) );
1075  else
1076  fpfield->Offset( wxPoint( 100, 0 ) );
1077  }
1078 
1079  fpfield->SetText( aFootPrint );
1080  fpfield->SetVisible( aSetVisible );
1081 
1082  found = true;
1083  }
1084  }
1085 
1086  return found;
1087 }
1088 
1089 
1091  bool aFullConnection )
1092 {
1093  SCH_ITEM* item;
1094  EDA_ITEM* tmp;
1095  EDA_ITEMS list;
1096 
1097  // Clear flags member for all items.
1100 
1101  if( GetNode( aPosition, list ) == 0 )
1102  return 0;
1103 
1104  for( size_t i = 0; i < list.size(); i++ )
1105  {
1106  item = (SCH_ITEM*) list[ i ];
1108 
1109  /* Put this structure in the picked list: */
1110  ITEM_PICKER picker( item, UR_DELETED );
1111  aList.PushItem( picker );
1112  }
1113 
1114  // Mark all wires, junctions, .. connected to the item(s) found.
1115  if( aFullConnection )
1116  {
1117  SCH_LINE* segment;
1118 
1119  for( item = m_drawList.begin(); item; item = item->Next() )
1120  {
1121  if( !(item->GetFlags() & SELECTEDNODE) )
1122  continue;
1123 
1124  if( item->Type() != SCH_LINE_T )
1125  continue;
1126 
1127  MarkConnections( (SCH_LINE*) item );
1128  }
1129 
1130  // Search all attached wires (i.e wire with one new dangling end )
1131  for( item = m_drawList.begin(); item; item = item->Next() )
1132  {
1133  bool noconnect = false;
1134 
1135  if( item->GetFlags() & STRUCT_DELETED )
1136  continue; // Already seen
1137 
1138  if( !(item->GetFlags() & CANDIDATE) )
1139  continue; // not a candidate
1140 
1141  if( item->Type() != SCH_LINE_T )
1142  continue;
1143 
1144  item->SetFlags( SKIP_STRUCT );
1145 
1146  segment = (SCH_LINE*) item;
1147 
1148  /* If the wire start point is connected to a wire that was already found
1149  * and now is not connected, add the wire to the list. */
1150  for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
1151  {
1152  // Ensure tmp is a previously deleted segment:
1153  if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
1154  continue;
1155 
1156  if( tmp->Type() != SCH_LINE_T )
1157  continue;
1158 
1159  SCH_LINE* testSegment = (SCH_LINE*) tmp;
1160 
1161  // Test for segment connected to the previously deleted segment:
1162  if( testSegment->IsEndPoint( segment->GetStartPoint() ) )
1163  break;
1164  }
1165 
1166  // when tmp != NULL, segment is a new candidate:
1167  // put it in deleted list if
1168  // the start point is not connected to an other item (like pin)
1169  if( tmp && !CountConnectedItems( segment->GetStartPoint(), true ) )
1170  noconnect = true;
1171 
1172  /* If the wire end point is connected to a wire that has already been found
1173  * and now is not connected, add the wire to the list. */
1174  for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
1175  {
1176  // Ensure tmp is a previously deleted segment:
1177  if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
1178  continue;
1179 
1180  if( tmp->Type() != SCH_LINE_T )
1181  continue;
1182 
1183  SCH_LINE* testSegment = (SCH_LINE*) tmp;
1184 
1185  // Test for segment connected to the previously deleted segment:
1186  if( testSegment->IsEndPoint( segment->GetEndPoint() ) )
1187  break;
1188  }
1189 
1190  // when tmp != NULL, segment is a new candidate:
1191  // put it in deleted list if
1192  // the end point is not connected to an other item (like pin)
1193  if( tmp && !CountConnectedItems( segment->GetEndPoint(), true ) )
1194  noconnect = true;
1195 
1196  item->ClearFlags( SKIP_STRUCT );
1197 
1198  if( noconnect )
1199  {
1200  item->SetFlags( STRUCT_DELETED );
1201 
1202  ITEM_PICKER picker( item, UR_DELETED );
1203  aList.PushItem( picker );
1204 
1205  item = m_drawList.begin();
1206  }
1207  }
1208 
1209  // Get redundant junctions (junctions which connect < 3 end wires
1210  // and no pin)
1211  for( item = m_drawList.begin(); item; item = item->Next() )
1212  {
1213  if( item->GetFlags() & STRUCT_DELETED )
1214  continue;
1215 
1216  if( !(item->GetFlags() & CANDIDATE) )
1217  continue;
1218 
1219  if( item->Type() != SCH_JUNCTION_T )
1220  continue;
1221 
1222  SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
1223 
1224  if( CountConnectedItems( junction->GetPosition(), false ) <= 2 )
1225  {
1226  item->SetFlags( STRUCT_DELETED );
1227 
1228  ITEM_PICKER picker( item, UR_DELETED );
1229  aList.PushItem( picker );
1230  }
1231  }
1232 
1233  for( item = m_drawList.begin(); item; item = item->Next() )
1234  {
1235  if( item->GetFlags() & STRUCT_DELETED )
1236  continue;
1237 
1238  if( item->Type() != SCH_LABEL_T )
1239  continue;
1240 
1241  tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
1242 
1243  if( tmp && tmp->GetFlags() & STRUCT_DELETED )
1244  {
1245  item->SetFlags( STRUCT_DELETED );
1246 
1247  ITEM_PICKER picker( item, UR_DELETED );
1248  aList.PushItem( picker );
1249  }
1250  }
1251  }
1252 
1254 
1255  return aList.GetCount();
1256 }
1257 
1258 
1259 #if defined(DEBUG)
1260 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1261 {
1262  // for now, make it look like XML, expand on this later.
1263  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1264 
1265  for( EDA_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1266  {
1267  item->Show( nestLevel+1, os );
1268  }
1269 
1270  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1271 }
1272 #endif
1273 
1274 
1278 static bool SortByTimeStamp( const EDA_ITEM* item1, const EDA_ITEM* item2 )
1279 {
1280  int ii = item1->GetTimeStamp() - item2->GetTimeStamp();
1281 
1282  /* If the time stamps are the same, compare type in order to have component objects
1283  * before sheet object. This is done because changing the sheet time stamp
1284  * before the component time stamp could cause the current annotation to be lost.
1285  */
1286  if( ( ii == 0 && ( item1->Type() != item2->Type() ) ) && ( item1->Type() == SCH_SHEET_T ) )
1287  ii = -1;
1288 
1289  return ii < 0;
1290 }
1291 
1292 
1294 {
1295  m_index = 0;
1296  buildScreenList( ( !aSheet ) ? g_RootSheet : aSheet );
1297 }
1298 
1299 
1301 {
1302 }
1303 
1304 
1306 {
1307  m_index = 0;
1308 
1309  if( m_screens.size() > 0 )
1310  return m_screens[0];
1311 
1312  return NULL;
1313 }
1314 
1315 
1317 {
1318  if( m_index < m_screens.size() )
1319  m_index++;
1320 
1321  return GetScreen( m_index );
1322 }
1323 
1324 
1325 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1326 {
1327  if( aIndex < m_screens.size() )
1328  return m_screens[ aIndex ];
1329 
1330  return NULL;
1331 }
1332 
1333 
1335 {
1336  if( aScreen == NULL )
1337  return;
1338 
1339  for( unsigned int i = 0; i < m_screens.size(); i++ )
1340  {
1341  if( m_screens[i] == aScreen )
1342  return;
1343  }
1344 
1345  m_screens.push_back( aScreen );
1346 }
1347 
1348 
1350 {
1351  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1352  {
1353  SCH_SCREEN* screen = aSheet->GetScreen();
1354 
1355  addScreenToList( screen );
1356 
1357  EDA_ITEM* strct = screen->GetDrawItems();
1358 
1359  while( strct )
1360  {
1361  if( strct->Type() == SCH_SHEET_T )
1362  {
1363  buildScreenList( ( SCH_SHEET* )strct );
1364  }
1365 
1366  strct = strct->Next();
1367  }
1368  }
1369 }
1370 
1371 
1373 {
1374  for( size_t i = 0; i < m_screens.size(); i++ )
1375  m_screens[i]->ClearAnnotation( NULL );
1376 }
1377 
1378 
1380 {
1381  for( size_t i = 0; i < m_screens.size(); i++ )
1382  {
1383  // if wire list has changed, delete the undo/redo list to avoid
1384  // pointer problems with deleted data.
1385  if( m_screens[i]->SchematicCleanUp() )
1386  m_screens[i]->ClearUndoRedoList();
1387  }
1388 }
1389 
1390 
1392 {
1393  EDA_ITEMS items;
1394  SCH_ITEM* item;
1395 
1396  for( size_t i = 0; i < m_screens.size(); i++ )
1397  m_screens[i]->GetHierarchicalItems( items );
1398 
1399  if( items.size() < 2 )
1400  return 0;
1401 
1402  sort( items.begin(), items.end(), SortByTimeStamp );
1403 
1404  int count = 0;
1405 
1406  for( size_t ii = 0; ii < items.size() - 1; ii++ )
1407  {
1408  item = (SCH_ITEM*)items[ii];
1409 
1410  SCH_ITEM* nextItem = (SCH_ITEM*)items[ii + 1];
1411 
1412  if( item->GetTimeStamp() == nextItem->GetTimeStamp() )
1413  {
1414  count++;
1415 
1416  // for a component, update its Time stamp and its paths
1417  // (m_PathsAndReferences field)
1418  if( item->Type() == SCH_COMPONENT_T )
1419  ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
1420 
1421  // for a sheet, update only its time stamp (annotation of its
1422  // components will be lost)
1423  // @todo: see how to change sheet paths for its cmp list (can
1424  // be possible in most cases)
1425  else
1426  item->SetTimeStamp( GetNewTimeStamp() );
1427  }
1428  }
1429 
1430  return count;
1431 }
1432 
1433 
1435 {
1436  SCH_ITEM* item;
1437  SCH_ITEM* nextItem;
1438  SCH_MARKER* marker;
1439  SCH_SCREEN* screen;
1440 
1441  for( screen = GetFirst(); screen; screen = GetNext() )
1442  {
1443  for( item = screen->GetDrawItems(); item; item = nextItem )
1444  {
1445  nextItem = item->Next();
1446 
1447  if( item->Type() != SCH_MARKER_T )
1448  continue;
1449 
1450  marker = (SCH_MARKER*) item;
1451 
1452  if( marker->GetMarkerType() != aMarkerType )
1453  continue;
1454 
1455  screen->DeleteItem( marker );
1456  }
1457  }
1458 }
1459 
1460 
1462  enum MARKER_BASE::MARKER_SEVERITY aSeverity )
1463 {
1464  int count = 0;
1465 
1466  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1467  {
1468  for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
1469  {
1470  if( item->Type() != SCH_MARKER_T )
1471  continue;
1472 
1473  SCH_MARKER* marker = (SCH_MARKER*) item;
1474 
1475  if( ( aMarkerType != MARKER_BASE::MARKER_UNSPEC ) &&
1476  ( marker->GetMarkerType() != aMarkerType ) )
1477  continue;
1478 
1479  if( aSeverity == MARKER_BASE::MARKER_SEVERITY_UNSPEC ||
1480  aSeverity == marker->GetErrorLevel() )
1481  count++;
1482  }
1483  }
1484 
1485  return count;
1486 }
1487 
1488 
1490 {
1491  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1492  screen->UpdateSymbolLinks( aForce );
1493 }
1494 
1495 
1497 {
1498  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1499  screen->TestDanglingEnds();
1500 }
1501 
1502 
1504 {
1505  SCH_COMPONENT* symbol;
1506  SCH_ITEM* item;
1507  SCH_ITEM* nextItem;
1508  SCH_SCREEN* screen;
1509  unsigned cnt = 0;
1510 
1511  for( screen = GetFirst(); screen; screen = GetNext() )
1512  {
1513  for( item = screen->GetDrawItems(); item; item = nextItem )
1514  {
1515  nextItem = item->Next();
1516 
1517  if( item->Type() != SCH_COMPONENT_T )
1518  continue;
1519 
1520  cnt += 1;
1521  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1522 
1523  if( !symbol->GetLibId().GetLibNickname().empty() )
1524  return false;
1525  }
1526  }
1527 
1528  if( cnt == 0 )
1529  return false;
1530 
1531  return true;
1532 }
1533 
1534 
1535 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1536 {
1537  SCH_COMPONENT* symbol;
1538  SCH_ITEM* item;
1539  SCH_ITEM* nextItem;
1540  SCH_SCREEN* screen;
1541  wxString nickname;
1542 
1543  for( screen = GetFirst(); screen; screen = GetNext() )
1544  {
1545  for( item = screen->GetDrawItems(); item; item = nextItem )
1546  {
1547  nextItem = item->Next();
1548 
1549  if( item->Type() != SCH_COMPONENT_T )
1550  continue;
1551 
1552  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1553 
1554  nickname = symbol->GetLibId().GetLibNickname();
1555 
1556  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1557  aLibNicknames.Add( nickname );;
1558  }
1559  }
1560 
1561  return aLibNicknames.GetCount();
1562 }
1563 
1564 
1565 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1566 {
1567  SCH_COMPONENT* symbol;
1568  SCH_ITEM* item;
1569  SCH_ITEM* nextItem;
1570  SCH_SCREEN* screen;
1571  int cnt = 0;
1572 
1573  for( screen = GetFirst(); screen; screen = GetNext() )
1574  {
1575  for( item = screen->GetDrawItems(); item; item = nextItem )
1576  {
1577  nextItem = item->Next();
1578 
1579  if( item->Type() != SCH_COMPONENT_T )
1580  continue;
1581 
1582  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1583 
1584  if( symbol->GetLibId().GetLibNickname() != aFrom )
1585  continue;
1586 
1587  LIB_ID id = symbol->GetLibId();
1588  id.SetLibNickname( aTo );
1589  symbol->SetLibId( id );
1590  cnt++;
1591  }
1592  }
1593 
1594  return cnt;
1595 }
void SetTextAngle(double aAngle)
Definition: eda_text.h:156
Definition of the SCH_SHEET class for Eeschema.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
#define DIM(x)
of elements in an array
Definition: macros.h:98
bool IsBusLabel(const wxString &aLabel)
Function IsBusLabel test if aLabel has a bus notation.
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
Class KIWAY_HOLDER is a mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_player.h:48
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:229
int CountConnectedItems(const wxPoint &aPos, bool aTestJunctions) const
Definition: sch_screen.cpp:670
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:269
SCH_SCREEN * GetNext()
SCH_SHEET_PIN * GetPin(const wxPoint &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:370
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Class TYPE_COLLECTOR merely gathers up all SCH_ITEMs of a given set of KICAD_T type(s).
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
Definition: sch_sheet.h:159
PART_REF & GetPartRef()
void DeleteAllMarkers(enum MARKER_BASE::TYPEMARKER aMarkerType)
Delete all electronic rules check markers of aMarkerType from all the screens in the list...
T * Remove(T *aElement)
Function Remove removes aElement from the list, but does not delete it.
Definition: dlist.h:211
SCH_SCREEN * GetScreen(unsigned int aIndex) const
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
int GetUnit() const
Base schematic object class definition.
virtual void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList)
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points...
static double SchematicZoomList[]
Definition: sch_screen.cpp:64
SCH_SHEET * GetSheet(const wxString &aName)
Returns a sheet object pointer that is named aName.
Definition: sch_screen.cpp:633
bool BreakSegment(const wxPoint &aPoint)
Checks every wire and bus for a intersection at aPoint and break into two segments at aPoint if an in...
Definition: sch_screen.cpp:897
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
SCH_LINE_TEST_T
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:138
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in m_drawL...
Definition: sch_screen.cpp:487
the 3d code uses this value
Definition: typeinfo.h:80
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i...
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:223
#define SELECTEDNODE
flag indicating that the structure has already selected
Definition: base_struct.h:135
void SetVisible(bool aVisible)
Definition: eda_text.h:175
int m_refCount
Number of sheets referencing this screen.
time_t GetNewTimeStamp()
Definition: common.cpp:166
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
bool IsSelected() const
Definition: base_struct.h:235
SCH_SCREEN(KIWAY *aKiway)
Constructor.
Definition: sch_screen.cpp:93
static const KICAD_T ComponentsOnly[]
A scan list for schematic component items only.
void SetOrigin(const wxPoint &pos)
T * begin() const
Definition: dlist.h:218
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
wxPoint GetEndPoint() const
Definition: sch_line.h:80
SCH_LINE * Next() const
Definition: sch_line.h:61
void Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:170
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.
wxPoint m_End() const
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:214
EDA_ITEM * Next() const
Definition: base_struct.h:220
bool BreakSegmentsOnJunctions()
Tests all junctions and bus entries in the schematic for intersections with wires and buses and break...
Definition: sch_screen.cpp:926
EDA_ITEM * GetItem(unsigned aIndex)
SCH_SCREENS(SCH_SHEET *aSheet=NULL)
#define CANDIDATE
flag indicating that the structure is connected
Definition: base_struct.h:137
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:41
SCH_LINEPenStyle
Definition: sch_line.cpp:45
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
int m_modification_sync
inequality with PART_LIBS::GetModificationHash() will trigger ResolveAll().
SCH_SCREEN * GetScreen()
Definition: sch_sheet.h:279
SCH_ITEM * Next() const
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:217
double GetTextAngle() const
Definition: eda_text.h:164
void SetEndPoint(const wxPoint &aPosition)
Definition: sch_line.h:82
enum TYPEMARKER GetMarkerType() const
wxPoint GetStartPoint() const
Definition: sch_line.h:76
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:41
static GRID_TYPE SchematicGridList[]
Definition: sch_screen.cpp:82
bool MergeOverlap(SCH_LINE *aLine)
Check line against aLine to see if it overlaps and merge if it does.
Definition: sch_line.cpp:355
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:69
#define IS_DRAGGED
Item being dragged.
Definition: base_struct.h:129
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:989
const wxPoint & GetOrigin() const
int GetConvert() const
unsigned int m_index
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item...
Definition: sch_field.cpp:451
#define SELECTED
Definition: base_struct.h:134
Class UNDO_REDO_CONTAINER is a holder to handle alist of undo (or redo) command.
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item...
Definition: sch_line.cpp:641
void SetLibId(const LIB_ID &aName, PART_LIBS *aLibs=NULL)
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:186
MARKER_SEVERITY GetErrorLevel() const
TITLE_BLOCK m_titles
int GetConnection(const wxPoint &aPosition, PICKED_ITEMS_LIST &aList, bool aFullConnection)
Adds all of the wires and junctions to aList that make up a connection to the object at aPosition...
void addConnectedItemsToBlock(const wxPoint &aPosition)
Add items connected at aPosition to the block pick list.
Definition: sch_screen.cpp:796
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:267
PAGE_INFO m_paper
The size of the paper to print or plot on.
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:55
void GetHierarchicalItems(EDA_ITEMS &aItems)
Add all schematic sheet and component objects in the screen to aItems.
Definition: sch_screen.cpp:707
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
int UpdatePickList()
Add all the items in the screen within the block selection rectangle to the pick list.
Definition: sch_screen.cpp:840
bool empty() const
Definition: utf8.h:108
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
bool SchematicCleanUp()
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
Definition: sch_screen.cpp:438
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_junction.h:88
static void ResolveAll(const SCH_COLLECTOR &aComponents, PART_LIBS *aLibs)
bool m_Center
Center on screen.
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:176
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:544
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
void MarkConnections(SCH_LINE *aSegment)
Add all wires and junctions connected to aSegment which are not connected any component pin to aItemL...
Definition: sch_screen.cpp:307
wxPoint GetPinPhysicalPosition(LIB_PIN *Pin)
virtual bool IsConnectable() const
Function IsConnectable returns true if the schematic item can connect to another schematic item...
void SetStartPoint(const wxPoint &aPosition)
Definition: sch_line.h:78
virtual void ClearUndoRedoList()
Function ClearUndoRedoList clear undo and redo list, using ClearUndoORRedoList() picked items are del...
void SchematicCleanUp()
Merge and break wire segments in the entire schematic hierarchy.
void Clear()
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:153
void Draw(EDA_DRAW_PANEL *aCanvas, wxDC *aDC, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED)
Draw all the items in the screen to aCanvas.
Definition: sch_screen.cpp:513
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:136
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:257
void SetFlags(STATUS_FLAGS aFlags)
int GetNode(const wxPoint &aPosition, EDA_ITEMS &aList)
Return all the items at aPosition that form a node.
Definition: sch_screen.cpp:955
SCH_SHEET_PIN * GetSheetLabel(const wxPoint &aPosition)
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:650
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:61
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)
bool SetZoom(double iu_per_du)
Function SetZoom adjusts the current zoom factor.
int GetUnit() const
Class SCH_SHEET_PATH.
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
void SetItem(EDA_ITEM *aItem)
bool SetPickerFlags(STATUS_FLAGS aFlags, unsigned aIdx)
Function SetPickerFlags set the flags of the picker (usually to the picked item m_Flags value) ...
void SelectBlockItems()
Create a list of items found when a block command is initiated.
Definition: sch_screen.cpp:721
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:164
time_t GetTimeStamp() const
Definition: base_struct.h:218
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
unsigned GetCount() const
Function GetCount.
void Plot(PLOTTER *aPlotter)
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:542
int GetMarkerCount(enum MARKER_BASE::TYPEMARKER aMarkerType, enum MARKER_BASE::MARKER_SEVERITY aSeverity)
Return the number of ERC markers of aMarkerType from all of the screens in the list.
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:219
DLIST< SCH_ITEM > m_drawList
Object list for the screen.
Definition of the NETLIST_OBJECT class.
void Normalize()
Function Normalize ensures that the height ant width are positive.
Field Value of part, i.e. "3.3K".
bool IsEndPoint(const wxPoint &aPoint) const
Definition: sch_line.h:69
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:131
Base plotter engine class.
Definition: class_plotter.h:97
SCH_ITEM * GetDrawItems() const
void addScreenToList(SCH_SCREEN *aScreen)
void SetSize(const wxSize &size)
Definition the SCH_COMPONENT class for Eeschema.
void AddGrid(const GRID_TYPE &grid)
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer)
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:367
see class PGM_BASE
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in the ful...
void TestDanglingEnds()
SCH_TEXT * GetLabel(const wxPoint &aPosition, int aAccuracy=0)
Return a label item located at aPosition.
Segment description base class to describe items which have 2 end points (track, wire, draw line ...)
Definition: sch_line.h:41
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
Function GetPickedItem.
std::vector< SCH_SCREEN * > m_screens
int GetFieldCount() const
Return the number of fields in this symbol.
Class GRID_TYPE is for grid arrays.
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=NOT_USED) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:215
void Append(SCH_ITEM *aItem)
void ClearAnnotation()
Clear the annotation for all components in the hierarchy.
#define max(a, b)
Definition: auxiliary.h:86
bool IsConnected(const wxPoint &aPoint) const
Function IsConnected tests the item to see if it is connected to aPoint.
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:876
void SetCurItem(SCH_ITEM *aItem)
Sets the currently selected object, m_CurrentItem.
#define ENDPOINT
Definition: base_struct.h:133
virtual bool IsSelectStateChanged(const wxRect &aRect)
Function IsSelectStateChanged checks if the selection state of an item inside aRect has changed...
Class EDA_RECT handles the component boundary box.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
wxPoint GetPosition() const override
Function GetPosition.
const LIB_ID & GetLibId() const
void Collect(SCH_ITEM *aBoard, const KICAD_T aScanList[])
Function Collect scans a BOARD_ITEM using this class's Inspector method, which does the collection...
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
The common library.
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_COMPONENT **aComponent=NULL, bool aEndPointOnly=false) const
Test the screen for a component pin item at aPosition.
Definition: sch_screen.cpp:577
bool IsDragging() const
Function IsDragging returns true if the current block command is a drag operation.
PICKED_ITEMS_LIST & GetItems()
void ExtractWires(DLIST< SCH_ITEM > &aList, bool aCreateCopy)
Extracts the old wires, junctions and buses.
Definition: sch_screen.cpp:253
virtual bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList)
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it's dangling state...
SCH_LINE * GetWireOrBus(const wxPoint &aPosition)
Return a wire or bus item located at aPosition.
Definition: sch_screen.cpp:974
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:268
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
void SetOwnership(bool Iown)
Function SetOwnership controls whether the list owns the objects and is responsible for deleteing the...
Definition: dlist.h:119
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:688
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
void ReplaceWires(DLIST< SCH_ITEM > &aWireList)
Replace all of the wires, buses, and junctions in the screen with aWireList.
Definition: sch_screen.cpp:281
SCH_SCREEN * GetFirst()
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:570
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:555
const wxSize & GetTextSize() const
Definition: eda_text.h:215
bool IsJunctionNeeded(const wxPoint &aPosition)
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:349
Definition for part library class.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:98
int SetGrid(const wxRealPoint &size)
set the current grid size m_Grid.
bool CheckIfOnDrawList(SCH_ITEM *st)
Definition: sch_screen.cpp:199
wxString GetName() const
Definition: sch_sheet.h:267
const wxSize & GetSize() const
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nickames into aLibNicknames.
static bool SortByTimeStamp(const EDA_ITEM *item1, const EDA_ITEM *item2)
Sort a list of schematic items by time stamp and type.
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Implementation of the label properties dialog.
unsigned GetCount() const
void Insert(T *aNewElement, T *aElementAfterMe)
Function Insert puts aNewElement just in front of aElementAfterMe in the list sequence.
Definition: dlist.h:200
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
std::vector< double > m_ZoomList
standard zoom (i.e. scale) coefficients.
void IncRefCount()
Definition: sch_screen.cpp:125
virtual wxString GetClass() const override
Function GetClass returns the class name.
#define STARTPOINT
Definition: base_struct.h:132
virtual void SetText(const wxString &aText)
Definition: eda_text.h:141
int GetConvert() const
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
void PushItem(ITEM_PICKER &aItem)
Function PushItem adds aItem to the list of items.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
wxPoint GetPosition() const override
Function GetPosition.
bool SetComponentFootprint(SCH_SHEET_PATH *aSheetPath, const wxString &aReference, const wxString &aFootPrint, bool aSetVisible)
Search this screen for a symbol with aReference and set the footprint field to aFootPrint if found...
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)