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