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( (aType == SCH_FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
219  {
220  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
221 
222  for( int i = REFERENCE; i < component->GetFieldCount(); i++ )
223  {
224  SCH_FIELD* field = component->GetField( i );
225 
226  if( field->HitTest( aPosition, aAccuracy ) )
227  return (SCH_ITEM*) field;
228  }
229  }
230  else if( (aType == SCH_SHEET_PIN_T) && (item->Type() == SCH_SHEET_T) )
231  {
232  SCH_SHEET* sheet = (SCH_SHEET*)item;
233 
234  SCH_SHEET_PIN* label = sheet->GetPin( aPosition );
235 
236  if( label )
237  return (SCH_ITEM*) label;
238  }
239  else if( ( ( item->Type() == aType ) || ( aType == NOT_USED ) )
240  && item->HitTest( aPosition, aAccuracy ) )
241  {
242  return item;
243  }
244  }
245 
246  return NULL;
247 }
248 
249 
250 void SCH_SCREEN::ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy )
251 {
252  SCH_ITEM* item;
253  SCH_ITEM* next_item;
254 
255  for( item = m_drawList.begin(); item; item = next_item )
256  {
257  next_item = item->Next();
258 
259  switch( item->Type() )
260  {
261  case SCH_JUNCTION_T:
262  case SCH_LINE_T:
263  m_drawList.Remove( item );
264  aList.Append( item );
265 
266  if( aCreateCopy )
267  m_drawList.Insert( (SCH_ITEM*) item->Clone(), next_item );
268 
269  break;
270 
271  default:
272  break;
273  }
274  }
275 }
276 
277 
279 {
280  SCH_ITEM* item;
281  SCH_ITEM* next_item;
282 
283  for( item = m_drawList.begin(); item; item = next_item )
284  {
285  next_item = item->Next();
286 
287  switch( item->Type() )
288  {
289  case SCH_JUNCTION_T:
290  case SCH_LINE_T:
291  Remove( item );
292  delete item;
293  break;
294 
295  default:
296  break;
297  }
298  }
299 
300  m_drawList.Append( aWireList );
301 }
302 
303 
305 {
306  wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T),
307  wxT( "Invalid object pointer." ) );
308 
309  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
310  {
311  if( item->GetFlags() & CANDIDATE )
312  continue;
313 
314  if( item->Type() == SCH_JUNCTION_T )
315  {
316  SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
317 
318  if( aSegment->IsEndPoint( junction->GetPosition() ) )
319  item->SetFlags( CANDIDATE );
320 
321  continue;
322  }
323 
324  if( item->Type() != SCH_LINE_T )
325  continue;
326 
327  SCH_LINE* segment = (SCH_LINE*) item;
328 
329  if( aSegment->IsEndPoint( segment->GetStartPoint() )
330  && !GetPin( segment->GetStartPoint(), NULL, true ) )
331  {
332  item->SetFlags( CANDIDATE );
333  MarkConnections( segment );
334  }
335 
336  if( aSegment->IsEndPoint( segment->GetEndPoint() )
337  && !GetPin( segment->GetEndPoint(), NULL, true ) )
338  {
339  item->SetFlags( CANDIDATE );
340  MarkConnections( segment );
341  }
342  }
343 }
344 
345 
346 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew )
347 {
348  bool has_nonparallel[2] = { false };
349  int end_count[2] = { 0 };
350  int pin_count = 0;
351 
352  std::vector<SCH_LINE*> lines[2];
353 
354  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
355  {
356  if( item->GetFlags() & STRUCT_DELETED )
357  continue;
358 
359  if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
360  return false;
361 
362  if( ( item->Type() == SCH_LINE_T )
363  && ( item->HitTest( aPosition, 0 ) ) )
364  {
365  if( item->GetLayer() == LAYER_WIRE )
366  lines[0].push_back( (SCH_LINE*) item );
367  else if( item->GetLayer() == LAYER_BUS )
368  lines[1].push_back( (SCH_LINE*) item );
369  }
370 
371  if( ( item->Type() == SCH_COMPONENT_T )
372  && ( item->IsConnected( aPosition ) ) )
373  pin_count++;
374  }
375 
376  for( int i = 0; i < 2; i++ )
377  {
378  bool removed_overlapping = false;
379  end_count[i] = lines[i].size();
380 
381  for( auto line = lines[i].begin(); line < lines[i].end(); line++ )
382  {
383  // Consider ending on a line to be equivalent to two endpoints because
384  // we will want to split the line if anything else connects
385  if( !(*line)->IsEndPoint( aPosition ) )
386  end_count[i]++;
387 
388  for( auto second_line = lines[i].end() - 1; second_line > line; second_line-- )
389  {
390  if( !(*line)->IsParallel( *second_line ) )
391  has_nonparallel[i] = true;
392  else if( !removed_overlapping
393  && (*line)->IsSameQuadrant( *second_line, aPosition ) )
394  {
400  removed_overlapping = true;
401  end_count[i]--;
402  }
403  }
404  }
405  }
406 
407  //
408 
409  // If there are three or more endpoints
410  if( pin_count + end_count[0] > 2 )
411  return true;
412 
413  // If there is at least one segment that ends on a non-parallel line or
414  // junction of two other lines
415  if( has_nonparallel[0] && end_count[0] > 2 )
416  return true;
417 
418  // Check for bus - bus junction requirements
419  if( has_nonparallel[1] && end_count[1] > 2 )
420  return true;
421 
422  return false;
423 }
424 
425 
426 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
427 {
428  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
429  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
430 
431  SCH_SHEET_PIN* label;
432  SCH_TEXT* text;
433 
434  switch( aLayer )
435  {
436  case LAYER_BUS:
437 
438  if( GetBus( aPosition ) )
439  return true;
440 
441  label = GetSheetLabel( aPosition );
442 
443  if( label && IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
444  return true;
445 
446  text = GetLabel( aPosition );
447 
448  if( text && IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
449  && (text->Type() != SCH_LABEL_T) )
450  return true;
451 
452  break;
453 
454  case LAYER_NOTES:
455 
456  if( GetLine( aPosition ) )
457  return true;
458 
459  break;
460 
461  case LAYER_WIRE:
463  return true;
464 
465  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_BUS_ENTRY_T) )
466  return true;
467 
468  if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_JUNCTION_T ) )
469  return true;
470 
471  if( GetPin( aPosition, NULL, true ) )
472  return true;
473 
474  if( GetWire( aPosition ) )
475  return true;
476 
477  text = GetLabel( aPosition );
478 
479  if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
480  return true;
481 
482  label = GetSheetLabel( aPosition );
483 
484  if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->GetText() ) )
485  return true;
486 
487  break;
488 
489  default:
490  break;
491  }
492 
493  return false;
494 }
495 
496 
497 void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
498 {
499  // Initialize or reinitialize the pointer to the LIB_PART for each component
500  // found in m_drawList, but only if needed (change in lib or schematic)
501  // therefore the calculation time is usually very low.
502  if( m_drawList.GetCount() )
503  {
504  SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
505  int mod_hash = libs->GetModifyHash();
507 
509 
510  // Must we resolve?
511  if( (m_modification_sync != mod_hash) || aForce )
512  {
513  SCH_COMPONENT::ResolveAll( c, *libs, Prj().SchLibs()->GetCacheLibrary() );
514 
515  m_modification_sync = mod_hash; // note the last mod_hash
516  }
517  // Resolving will update the pin caches but we must ensure that this happens
518  // even if the libraries don't change.
519  else
521  }
522 }
523 
524 
525 void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode, COLOR4D aColor )
526 {
527  /* note: SCH_SCREEN::Draw is useful only for schematic.
528  * library editor and library viewer do not use m_drawList, and therefore
529  * their SCH_SCREEN::Draw() draws nothing
530  */
531  std::vector< SCH_ITEM* > junctions;
532 
533  // Ensure links are up to date, even if a library was reloaded for some reason:
535 
536  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
537  {
538  if( item->IsMoving() || item->IsResized() )
539  continue;
540 
541  if( item->Type() == SCH_JUNCTION_T )
542  junctions.push_back( item );
543  else
544  // uncomment line below when there is a virtual EDA_ITEM::GetBoundingBox()
545  // if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
546  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
547  }
548 
549  for( auto item : junctions )
550  item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
551 }
552 
553 
554 void SCH_SCREEN::Plot( PLOTTER* aPlotter )
555 {
556  // Ensure links are up to date, even if a library was reloaded for some reason:
558 
559  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
560  {
561  aPlotter->SetCurrentLineWidth( item->GetPenSize() );
562  item->Plot( aPlotter );
563  }
564 }
565 
566 
568 {
569  if( aItemCount == 0 )
570  return;
571 
572  for( auto& command : aList.m_CommandsList )
573  {
574  command->ClearListAndDeleteItems();
575  delete command;
576  }
577 
578  aList.m_CommandsList.clear();
579 }
580 
581 
583 {
584  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
585  item->ClearFlags();
586 }
587 
588 
589 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent,
590  bool aEndPointOnly ) const
591 {
592  SCH_ITEM* item;
593  SCH_COMPONENT* component = NULL;
594  LIB_PIN* pin = NULL;
595 
596  for( item = m_drawList.begin(); item; item = item->Next() )
597  {
598  if( item->Type() != SCH_COMPONENT_T )
599  continue;
600 
601  component = (SCH_COMPONENT*) item;
602 
603  if( aEndPointOnly )
604  {
605  pin = NULL;
606 
607  auto part = component->GetPartRef().lock();
608 
609  if( !part )
610  continue;
611 
612  for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
613  {
614  // Skip items not used for this part.
615  if( component->GetUnit() && pin->GetUnit() &&
616  ( pin->GetUnit() != component->GetUnit() ) )
617  continue;
618 
619  if( component->GetConvert() && pin->GetConvert() &&
620  ( pin->GetConvert() != component->GetConvert() ) )
621  continue;
622 
623  if(component->GetPinPhysicalPosition( pin ) == aPosition )
624  break;
625  }
626  if( pin )
627  break;
628  }
629  else
630  {
631  pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
632 
633  if( pin )
634  break;
635  }
636  }
637 
638  if( pin && aComponent )
639  *aComponent = component;
640 
641  return pin;
642 }
643 
644 
645 SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName )
646 {
647  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
648  {
649  if( item->Type() != SCH_SHEET_T )
650  continue;
651 
652  SCH_SHEET* sheet = (SCH_SHEET*) item;
653 
654  if( aName.CmpNoCase( sheet->GetName() ) == 0 )
655  return sheet;
656  }
657 
658  return NULL;
659 }
660 
661 
663 {
664  SCH_SHEET_PIN* sheetPin = NULL;
665 
666  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
667  {
668  if( item->Type() != SCH_SHEET_T )
669  continue;
670 
671  SCH_SHEET* sheet = (SCH_SHEET*) item;
672  sheetPin = sheet->GetPin( aPosition );
673 
674  if( sheetPin )
675  break;
676  }
677 
678  return sheetPin;
679 }
680 
681 
682 int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
683 {
684  SCH_ITEM* item;
685  int count = 0;
686 
687  for( item = m_drawList.begin(); item; item = item->Next() )
688  {
689  if( item->Type() == SCH_JUNCTION_T && !aTestJunctions )
690  continue;
691 
692  if( item->IsConnected( aPos ) )
693  count++;
694  }
695 
696  return count;
697 }
698 
699 
701 {
702  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
703  {
704  if( item->Type() == SCH_COMPONENT_T )
705  {
706  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
707 
708  component->ClearAnnotation( aSheetPath );
709 
710  // Clear the modified component flag set by component->ClearAnnotation
711  // because we do not use it here and we should not leave this flag set,
712  // when an edition is finished:
713  component->ClearFlags();
714  }
715  }
716 }
717 
718 
720 {
721  SCH_ITEM* item = m_drawList.begin();
722 
723  while( item )
724  {
725  if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
726  aItems.push_back( item );
727 
728  item = item->Next();
729  }
730 }
731 
732 
734 {
735  auto addConnections = [ this ]( SCH_ITEM* item ) -> void
736  {
737  std::vector< wxPoint > connections;
738  item->GetConnectionPoints( connections );
739  for( auto conn : connections )
740  addConnectedItemsToBlock( item, conn );
741  };
742 
743  PICKED_ITEMS_LIST* pickedlist = &m_BlockLocate.GetItems();
744 
745  if( pickedlist->GetCount() == 0 )
746  return;
747 
749 
750  for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
751  {
752  SCH_ITEM* item = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
753  item->SetFlags( SELECTED );
754  }
755 
756  if( !m_BlockLocate.IsDragging() )
757  return;
758 
759  // Select all the items in the screen connected to the items in the block.
760  // be sure end lines that are on the block limits are seen inside this block
761  m_BlockLocate.Inflate( 1 );
762  unsigned last_select_id = pickedlist->GetCount();
763 
764  for( unsigned ii = 0; ii < last_select_id; ii++ )
765  {
766  SCH_ITEM* item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
767  item->SetFlags( IS_DRAGGED );
768 
769  if( item->Type() == SCH_LINE_T )
770  {
772 
773  if( !item->IsSelected() )
774  { // This is a special case:
775  // this selected wire has no ends in block.
776  // But it was selected (because it intersects the selecting area),
777  // so we must keep it selected and select items connected to it
778  // Note: another option could be: remove it from drag list
779  item->SetFlags( SELECTED | SKIP_STRUCT );
780  addConnections( item );
781  }
782 
783  pickedlist->SetPickerFlags( item->GetFlags(), ii );
784  }
785  else if( item->IsConnectable() )
786  {
787  addConnections( item );
788  }
789  }
790 
791  // Select the items that are connected to a block object that was added
792  // to our selection list in the last step.
793  for( unsigned ii = last_select_id; ii < pickedlist->GetCount(); ii++ )
794  {
795  SCH_ITEM* item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
796 
797  if( item->Type() == SCH_COMPONENT_T ||
798  item->Type() == SCH_BUS_BUS_ENTRY_T ||
799  item->Type() == SCH_BUS_WIRE_ENTRY_T ||
800  item->Type() == SCH_SHEET_T ||
801  ( item->Type() == SCH_LINE_T && !( item->GetFlags() & ( ENDPOINT | STARTPOINT ) ) ) )
802  {
803  item->SetFlags( IS_DRAGGED );
804  addConnections( item );
805  }
806  }
807 
808  m_BlockLocate.Inflate( -1 );
809 }
810 
811 
812 void SCH_SCREEN::addConnectedItemsToBlock( const SCH_ITEM* aItem, const wxPoint& position )
813 {
814  SCH_ITEM* item;
815  ITEM_PICKER picker;
816 
817  for( item = m_drawList.begin(); item; item = item->Next() )
818  {
819 
820  if( !item->IsConnectable() || ( item->GetFlags() & SKIP_STRUCT )
821  || !item->CanConnect( aItem ) || item == aItem )
822  continue;
823 
824  // A line having 2 ends, it can be tested twice: one time per end
825  if( item->Type() == SCH_LINE_T )
826  {
827  SCH_LINE* line = (SCH_LINE*) item;
828 
829  if( !item->HitTest( position ) )
830  continue;
831 
832  // First time through. Flags set to denote an end that is not moving
833  if( !item->IsSelected() )
834  item->SetFlags( CANDIDATE | STARTPOINT | ENDPOINT );
835 
836  if( line->GetStartPoint() == position )
837  item->ClearFlags( STARTPOINT );
838  else if( line->GetEndPoint() == position )
839  item->ClearFlags( ENDPOINT );
840  else
841  // This picks up items such as labels that can connect to the middle of a line
842  item->ClearFlags( STARTPOINT | ENDPOINT );
843  }
844  // We want to move a mid-connected label or bus entry when the full line is being moved
845  else if( !item->IsSelected()
846  && aItem->Type() == SCH_LINE_T
847  && !( aItem->GetFlags() & ( ENDPOINT | STARTPOINT ) ) )
848  {
849  std::vector< wxPoint > connections;
850  item->GetConnectionPoints( connections );
851 
852  for( auto conn : connections )
853  {
854  if( aItem->HitTest( conn ) )
855  {
856  item->SetFlags( CANDIDATE );
857  break;
858  }
859  }
860  }
861 
862  if( item->IsSelected() )
863  continue;
864 
865  if( ( item->GetFlags() & CANDIDATE ) || item->IsConnected( position ) ) // Deal with all non-line items
866  {
867  item->ClearFlags( CANDIDATE );
868  item->SetFlags( SELECTED );
869  picker.SetItem( item );
870  picker.SetFlags( item->GetFlags() );
871  m_BlockLocate.GetItems().PushItem( picker );
872  }
873  }
874 }
875 
876 
878 {
879  ITEM_PICKER picker;
880  EDA_RECT area;
881  unsigned count;
882 
884  area.SetSize( m_BlockLocate.GetSize() );
885  area.Normalize();
886 
887  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
888  {
889  // An item is picked if its bounding box intersects the reference area.
890  if( item->HitTest( area ) )
891  {
892  picker.SetItem( item );
893  m_BlockLocate.PushItem( picker );
894  }
895  }
896 
897  // if the block is composed of one item,
898  // select it as the current item
899  count = m_BlockLocate.GetCount();
900  if( count == 1 )
901  {
903  }
904  else
905  {
906  SetCurItem( NULL );
907  }
908 
909  return count;
910 }
911 
912 
914 {
915  SCH_ITEM* item;
916  std::vector< DANGLING_END_ITEM > endPoints;
917  bool hasStateChanged = false;
918 
919  for( item = m_drawList.begin(); item; item = item->Next() )
920  item->GetEndPoints( endPoints );
921 
922  for( item = m_drawList.begin(); item; item = item->Next() )
923  {
924  if( item->IsDanglingStateChanged( endPoints ) )
925  {
926  hasStateChanged = true;
927  }
928  }
929 
930  return hasStateChanged;
931 }
932 
933 
934 int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList )
935 {
936  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
937  {
938  if( item->Type() == SCH_LINE_T && item->HitTest( aPosition )
939  && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
940  {
941  aList.push_back( item );
942  }
943  else if( item->Type() == SCH_JUNCTION_T && item->HitTest( aPosition ) )
944  {
945  aList.push_back( item );
946  }
947  }
948 
949  return (int) aList.size();
950 }
951 
952 
954 {
955  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
956  {
957  if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition )
958  && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
959  {
960  return (SCH_LINE*) item;
961  }
962  }
963 
964  return NULL;
965 }
966 
967 
968 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
969  SCH_LINE_TEST_T aSearchType )
970 {
971  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
972  {
973  if( item->Type() != SCH_LINE_T )
974  continue;
975 
976  if( item->GetLayer() != aLayer )
977  continue;
978 
979  if( !item->HitTest( aPosition, aAccuracy ) )
980  continue;
981 
982  switch( aSearchType )
983  {
984  case ENTIRE_LENGTH_T:
985  return (SCH_LINE*) item;
986 
988  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
989  return (SCH_LINE*) item;
990  break;
991 
992  case END_POINTS_ONLY_T:
993  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
994  return (SCH_LINE*) item;
995  }
996  }
997 
998  return NULL;
999 }
1000 
1001 
1002 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
1003 {
1004  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1005  {
1006  switch( item->Type() )
1007  {
1008  case SCH_LABEL_T:
1009  case SCH_GLOBAL_LABEL_T:
1011  if( item->HitTest( aPosition, aAccuracy ) )
1012  return (SCH_TEXT*) item;
1013 
1014  default:
1015  ;
1016  }
1017  }
1018 
1019  return NULL;
1020 }
1021 
1022 
1023 bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
1024  const wxString& aFootPrint, bool aSetVisible )
1025 {
1026  SCH_COMPONENT* component;
1027  bool found = false;
1028 
1029  for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1030  {
1031  if( item->Type() != SCH_COMPONENT_T )
1032  continue;
1033 
1034  component = (SCH_COMPONENT*) item;
1035 
1036  if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
1037  {
1038  // Found: Init Footprint Field
1039 
1040  /* Give a reasonable value to the field position and
1041  * orientation, if the text is empty at position 0, because
1042  * it is probably not yet initialized
1043  */
1044  SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
1045  if( fpfield->GetText().IsEmpty()
1046  && ( fpfield->GetTextPos() == component->GetPosition() ) )
1047  {
1048  fpfield->SetTextAngle( component->GetField( VALUE )->GetTextAngle() );
1049  fpfield->SetTextPos( component->GetField( VALUE )->GetTextPos() );
1050  fpfield->SetTextSize( component->GetField( VALUE )->GetTextSize() );
1051 
1052  if( fpfield->GetTextAngle() == 0.0 )
1053  fpfield->Offset( wxPoint( 0, 100 ) );
1054  else
1055  fpfield->Offset( wxPoint( 100, 0 ) );
1056  }
1057 
1058  fpfield->SetText( aFootPrint );
1059  fpfield->SetVisible( aSetVisible );
1060 
1061  found = true;
1062  }
1063  }
1064 
1065  return found;
1066 }
1067 
1068 
1070  bool aFullConnection )
1071 {
1072  SCH_ITEM* item;
1073  EDA_ITEM* tmp;
1074  EDA_ITEMS list;
1075 
1076  // Clear flags member for all items.
1078 
1079  if( GetNode( aPosition, list ) == 0 )
1080  return 0;
1081 
1082  for( size_t i = 0; i < list.size(); i++ )
1083  {
1084  item = (SCH_ITEM*) list[ i ];
1086 
1087  /* Put this structure in the picked list: */
1088  ITEM_PICKER picker( item, UR_DELETED );
1089  aList.PushItem( picker );
1090  }
1091 
1092  // Mark all wires, junctions, .. connected to the item(s) found.
1093  if( aFullConnection )
1094  {
1095  SCH_LINE* segment;
1096 
1097  for( item = m_drawList.begin(); item; item = item->Next() )
1098  {
1099  if( !(item->GetFlags() & SELECTEDNODE) )
1100  continue;
1101 
1102  if( item->Type() != SCH_LINE_T )
1103  continue;
1104 
1105  MarkConnections( (SCH_LINE*) item );
1106  }
1107 
1108  // Search all attached wires (i.e wire with one new dangling end )
1109  for( item = m_drawList.begin(); item; item = item->Next() )
1110  {
1111  bool noconnect = false;
1112 
1113  if( item->GetFlags() & STRUCT_DELETED )
1114  continue; // Already seen
1115 
1116  if( !(item->GetFlags() & CANDIDATE) )
1117  continue; // not a candidate
1118 
1119  if( item->Type() != SCH_LINE_T )
1120  continue;
1121 
1122  item->SetFlags( SKIP_STRUCT );
1123 
1124  segment = (SCH_LINE*) item;
1125 
1126  /* If the wire start point is connected to a wire that was already found
1127  * and now is not connected, add the wire to the list. */
1128  for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
1129  {
1130  // Ensure tmp is a previously deleted segment:
1131  if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
1132  continue;
1133 
1134  if( tmp->Type() != SCH_LINE_T )
1135  continue;
1136 
1137  SCH_LINE* testSegment = (SCH_LINE*) tmp;
1138 
1139  // Test for segment connected to the previously deleted segment:
1140  if( testSegment->IsEndPoint( segment->GetStartPoint() ) )
1141  break;
1142  }
1143 
1144  // when tmp != NULL, segment is a new candidate:
1145  // put it in deleted list if
1146  // the start point is not connected to another item (like pin)
1147  if( tmp && !CountConnectedItems( segment->GetStartPoint(), true ) )
1148  noconnect = true;
1149 
1150  /* If the wire end point is connected to a wire that has already been found
1151  * and now is not connected, add the wire to the list. */
1152  for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
1153  {
1154  // Ensure tmp is a previously deleted segment:
1155  if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
1156  continue;
1157 
1158  if( tmp->Type() != SCH_LINE_T )
1159  continue;
1160 
1161  SCH_LINE* testSegment = (SCH_LINE*) tmp;
1162 
1163  // Test for segment connected to the previously deleted segment:
1164  if( testSegment->IsEndPoint( segment->GetEndPoint() ) )
1165  break;
1166  }
1167 
1168  // when tmp != NULL, segment is a new candidate:
1169  // put it in deleted list if
1170  // the end point is not connected to another item (like pin)
1171  if( tmp && !CountConnectedItems( segment->GetEndPoint(), true ) )
1172  noconnect = true;
1173 
1174  item->ClearFlags( SKIP_STRUCT );
1175 
1176  if( noconnect )
1177  {
1178  item->SetFlags( STRUCT_DELETED );
1179 
1180  ITEM_PICKER picker( item, UR_DELETED );
1181  aList.PushItem( picker );
1182 
1183  item = m_drawList.begin();
1184  }
1185  }
1186 
1187  for( item = m_drawList.begin(); item; item = item->Next() )
1188  {
1189  if( item->GetFlags() & STRUCT_DELETED )
1190  continue;
1191 
1192  if( item->Type() != SCH_LABEL_T )
1193  continue;
1194 
1195  tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
1196 
1197  if( tmp && ( tmp->GetFlags() & STRUCT_DELETED ) )
1198  {
1199  item->SetFlags( STRUCT_DELETED );
1200 
1201  ITEM_PICKER picker( item, UR_DELETED );
1202  aList.PushItem( picker );
1203  }
1204  }
1205  }
1206 
1208 
1209  return aList.GetCount();
1210 }
1211 
1212 
1213 #if defined(DEBUG)
1214 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1215 {
1216  // for now, make it look like XML, expand on this later.
1217  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1218 
1219  for( EDA_ITEM* item = m_drawList.begin(); item; item = item->Next() )
1220  {
1221  item->Show( nestLevel+1, os );
1222  }
1223 
1224  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1225 }
1226 #endif
1227 
1228 
1232 static bool SortByTimeStamp( const EDA_ITEM* item1, const EDA_ITEM* item2 )
1233 {
1234  int ii = item1->GetTimeStamp() - item2->GetTimeStamp();
1235 
1236  /* If the time stamps are the same, compare type in order to have component objects
1237  * before sheet object. This is done because changing the sheet time stamp
1238  * before the component time stamp could cause the current annotation to be lost.
1239  */
1240  if( ( ii == 0 && ( item1->Type() != item2->Type() ) ) && ( item1->Type() == SCH_SHEET_T ) )
1241  ii = -1;
1242 
1243  return ii < 0;
1244 }
1245 
1246 
1248 {
1249  m_index = 0;
1250  buildScreenList( ( !aSheet ) ? g_RootSheet : aSheet );
1251 }
1252 
1253 
1255 {
1256 }
1257 
1258 
1260 {
1261  m_index = 0;
1262 
1263  if( m_screens.size() > 0 )
1264  return m_screens[0];
1265 
1266  return NULL;
1267 }
1268 
1269 
1271 {
1272  if( m_index < m_screens.size() )
1273  m_index++;
1274 
1275  return GetScreen( m_index );
1276 }
1277 
1278 
1279 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1280 {
1281  if( aIndex < m_screens.size() )
1282  return m_screens[ aIndex ];
1283 
1284  return NULL;
1285 }
1286 
1287 
1289 {
1290  if( aScreen == NULL )
1291  return;
1292 
1293  for( unsigned int i = 0; i < m_screens.size(); i++ )
1294  {
1295  if( m_screens[i] == aScreen )
1296  return;
1297  }
1298 
1299  m_screens.push_back( aScreen );
1300 }
1301 
1302 
1304 {
1305  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1306  {
1307  SCH_SCREEN* screen = aSheet->GetScreen();
1308 
1309  addScreenToList( screen );
1310 
1311  EDA_ITEM* strct = screen->GetDrawItems();
1312 
1313  while( strct )
1314  {
1315  if( strct->Type() == SCH_SHEET_T )
1316  {
1317  buildScreenList( ( SCH_SHEET* )strct );
1318  }
1319 
1320  strct = strct->Next();
1321  }
1322  }
1323 }
1324 
1325 
1327 {
1328  for( size_t i = 0; i < m_screens.size(); i++ )
1329  m_screens[i]->ClearAnnotation( NULL );
1330 }
1331 
1333 {
1334  EDA_ITEMS items;
1335  SCH_ITEM* item;
1336 
1337  for( size_t i = 0; i < m_screens.size(); i++ )
1338  m_screens[i]->GetHierarchicalItems( items );
1339 
1340  if( items.size() < 2 )
1341  return 0;
1342 
1343  sort( items.begin(), items.end(), SortByTimeStamp );
1344 
1345  int count = 0;
1346 
1347  for( size_t ii = 0; ii < items.size() - 1; ii++ )
1348  {
1349  item = (SCH_ITEM*)items[ii];
1350 
1351  SCH_ITEM* nextItem = (SCH_ITEM*)items[ii + 1];
1352 
1353  if( item->GetTimeStamp() == nextItem->GetTimeStamp() )
1354  {
1355  count++;
1356 
1357  // for a component, update its Time stamp and its paths
1358  // (m_PathsAndReferences field)
1359  if( item->Type() == SCH_COMPONENT_T )
1360  ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
1361 
1362  // for a sheet, update only its time stamp (annotation of its
1363  // components will be lost)
1364  // @todo: see how to change sheet paths for its cmp list (can
1365  // be possible in most cases)
1366  else
1367  item->SetTimeStamp( GetNewTimeStamp() );
1368  }
1369  }
1370 
1371  return count;
1372 }
1373 
1374 
1376 {
1377  SCH_ITEM* item;
1378  SCH_ITEM* nextItem;
1379  SCH_MARKER* marker;
1380  SCH_SCREEN* screen;
1381 
1382  for( screen = GetFirst(); screen; screen = GetNext() )
1383  {
1384  for( item = screen->GetDrawItems(); item; item = nextItem )
1385  {
1386  nextItem = item->Next();
1387 
1388  if( item->Type() != SCH_MARKER_T )
1389  continue;
1390 
1391  marker = (SCH_MARKER*) item;
1392 
1393  if( marker->GetMarkerType() != aMarkerType )
1394  continue;
1395 
1396  screen->DeleteItem( marker );
1397  }
1398  }
1399 }
1400 
1401 
1403  enum MARKER_BASE::MARKER_SEVERITY aSeverity )
1404 {
1405  int count = 0;
1406 
1407  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1408  {
1409  for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
1410  {
1411  if( item->Type() != SCH_MARKER_T )
1412  continue;
1413 
1414  SCH_MARKER* marker = (SCH_MARKER*) item;
1415 
1416  if( ( aMarkerType != MARKER_BASE::MARKER_UNSPEC ) &&
1417  ( marker->GetMarkerType() != aMarkerType ) )
1418  continue;
1419 
1420  if( aSeverity == MARKER_BASE::MARKER_SEVERITY_UNSPEC ||
1421  aSeverity == marker->GetErrorLevel() )
1422  count++;
1423  }
1424  }
1425 
1426  return count;
1427 }
1428 
1429 
1431 {
1432  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1433  screen->UpdateSymbolLinks( aForce );
1434 }
1435 
1436 
1438 {
1439  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1440  screen->TestDanglingEnds();
1441 }
1442 
1443 
1445 {
1446  SCH_COMPONENT* symbol;
1447  SCH_ITEM* item;
1448  SCH_ITEM* nextItem;
1449  SCH_SCREEN* screen;
1450  unsigned cnt = 0;
1451 
1452  for( screen = GetFirst(); screen; screen = GetNext() )
1453  {
1454  for( item = screen->GetDrawItems(); item; item = nextItem )
1455  {
1456  nextItem = item->Next();
1457 
1458  if( item->Type() != SCH_COMPONENT_T )
1459  continue;
1460 
1461  cnt += 1;
1462  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1463  wxASSERT( symbol );
1464 
1465  if( !symbol->GetLibId().GetLibNickname().empty() )
1466  return false;
1467  }
1468  }
1469 
1470  if( cnt == 0 )
1471  return false;
1472 
1473  return true;
1474 }
1475 
1476 
1477 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1478 {
1479  SCH_COMPONENT* symbol;
1480  SCH_ITEM* item;
1481  SCH_ITEM* nextItem;
1482  SCH_SCREEN* screen;
1483  wxString nickname;
1484 
1485  for( screen = GetFirst(); screen; screen = GetNext() )
1486  {
1487  for( item = screen->GetDrawItems(); item; item = nextItem )
1488  {
1489  nextItem = item->Next();
1490 
1491  if( item->Type() != SCH_COMPONENT_T )
1492  continue;
1493 
1494  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1495  wxASSERT( symbol );
1496 
1497  nickname = symbol->GetLibId().GetLibNickname();
1498 
1499  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1500  aLibNicknames.Add( nickname );;
1501  }
1502  }
1503 
1504  return aLibNicknames.GetCount();
1505 }
1506 
1507 
1508 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1509 {
1510  SCH_COMPONENT* symbol;
1511  SCH_ITEM* item;
1512  SCH_ITEM* nextItem;
1513  SCH_SCREEN* screen;
1514  int cnt = 0;
1515 
1516  for( screen = GetFirst(); screen; screen = GetNext() )
1517  {
1518  for( item = screen->GetDrawItems(); item; item = nextItem )
1519  {
1520  nextItem = item->Next();
1521 
1522  if( item->Type() != SCH_COMPONENT_T )
1523  continue;
1524 
1525  symbol = dynamic_cast< SCH_COMPONENT* >( item );
1526  wxASSERT( symbol );
1527 
1528  if( symbol->GetLibId().GetLibNickname() != aFrom )
1529  continue;
1530 
1531  LIB_ID id = symbol->GetLibId();
1532  id.SetLibNickname( aTo );
1533  symbol->SetLibId( id );
1534  cnt++;
1535  }
1536  }
1537 
1538  return cnt;
1539 }
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:209
#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:682
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:266
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:371
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:346
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:645
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:120
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:497
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:117
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:232
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:217
EDA_ITEM * GetItem(unsigned aIndex)
SCH_SCREENS(SCH_SHEET *aSheet=NULL)
#define CANDIDATE
flag indicating that the structure is connected
Definition: base_struct.h:119
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:812
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:111
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:968
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:451
#define SELECTED
Definition: base_struct.h:116
Class UNDO_REDO_CONTAINER is a holder to handle alist of undo (or redo) command.
timestamp_t GetNewTimeStamp()
Definition: common.cpp:167
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:187
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:264
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:719
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:877
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:541
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:304
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:525
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:118
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:934
SCH_SHEET_PIN * GetSheetLabel(const wxPoint &aPosition)
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:662
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:733
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:554
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:426
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:913
void SetCurItem(SCH_ITEM *aItem)
Sets the currently selected object, m_CurrentItem.
Definition: sch_screen.h:182
size_t i
Definition: json11.cpp:597
#define ENDPOINT
Definition: base_struct.h:115
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:162
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:589
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:250
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:953
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:265
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:700
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:278
SCH_SCREEN * GetFirst()
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:582
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:567
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:101
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:215
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:214
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_screen.h:110
#define STARTPOINT
Definition: base_struct.h:114
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...
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T)
Definition: sch_screen.h:448