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