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