KiCad PCB EDA Suite
sch_edit_tool.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) 2019 CERN
5  * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <kiway.h>
26 #include <tool/picker_tool.h>
27 #include <tools/sch_edit_tool.h>
30 #include <tools/sch_move_tool.h>
31 #include <widgets/infobar.h>
32 #include <ee_actions.h>
33 #include <bitmaps.h>
34 #include <confirm.h>
35 #include <eda_item.h>
36 #include <reporter.h>
37 #include <string_utils.h>
38 #include <sch_item.h>
39 #include <sch_symbol.h>
40 #include <sch_sheet.h>
41 #include <sch_sheet_pin.h>
42 #include <sch_text.h>
43 #include <sch_bitmap.h>
44 #include <sch_view.h>
45 #include <sch_line.h>
46 #include <sch_bus_entry.h>
47 #include <sch_junction.h>
48 #include <sch_edit_frame.h>
49 #include <schematic.h>
52 #include <eeschema_id.h>
53 #include <status_popup.h>
54 #include <wx/gdicmn.h>
62 #include "sch_drawing_tools.h"
63 #include <math/util.h> // for KiROUND
64 #include <pgm_base.h>
66 #include <symbol_editor_settings.h>
68 #include <core/kicad_algo.h>
69 #include <wx/textdlg.h>
70 
71 
72 
74 {
75 public:
77  ACTION_MENU( true )
78  {
80  SetTitle( _( "Symbol Unit" ) );
81  }
82 
83 protected:
84  ACTION_MENU* create() const override
85  {
86  return new SYMBOL_UNIT_MENU();
87  }
88 
89 private:
90  void update() override
91  {
93  EE_SELECTION& selection = selTool->GetSelection();
94  SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
95 
96  Clear();
97 
98  if( !symbol )
99  {
100  Append( ID_POPUP_SCH_UNFOLD_BUS, _( "no symbol selected" ), wxEmptyString );
101  Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
102  return;
103  }
104 
105  int unit = symbol->GetUnit();
106 
107  if( !symbol->GetLibSymbolRef() || symbol->GetLibSymbolRef()->GetUnitCount() < 2 )
108  {
109  Append( ID_POPUP_SCH_UNFOLD_BUS, _( "symbol is not multi-unit" ), wxEmptyString );
110  Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
111  return;
112  }
113 
114  for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
115  {
116  wxString num_unit;
117  num_unit.Printf( _( "Unit %s" ), LIB_SYMBOL::SubReference( ii + 1, false ) );
118 
119  wxMenuItem * item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
120  wxITEM_CHECK );
121  if( unit == ii + 1 )
122  item->Check(true);
123 
124  // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_SYM_MAX
125  // See eeschema_id to modify this value.
127  break; // We have used all IDs for these submenus
128  }
129  }
130 };
131 
132 
134  EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
135 {
136  m_pickerItem = nullptr;
137 }
138 
139 
141 
143 {
145 
148 
149  wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
150 
151  auto hasElements =
152  [this]( const SELECTION& aSel )
153  {
154  return !m_frame->GetScreen()->Items().empty();
155  };
156 
157  auto sheetHasUndefinedPins =
158  []( const SELECTION& aSel )
159  {
160  if( aSel.Size() != 1 )
161  return false;
162 
163  if( !aSel.HasType( SCH_SHEET_T ) )
164  return false;
165 
166  SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aSel.Front() );
167 
168  wxCHECK( item, false );
169 
170  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( item );
171 
172  wxCHECK( sheet, false );
173 
174  return sheet->HasUndefinedPins();
175  };
176 
177  auto anyTextTool =
178  [this]( const SELECTION& aSel )
179  {
184  };
185 
186  auto duplicateCondition =
187  []( const SELECTION& aSel )
188  {
190  return false;
191 
192  return true;
193  };
194 
195  auto orientCondition =
196  []( const SELECTION& aSel )
197  {
198  if( aSel.Empty() )
199  return false;
200 
202  return false;
203 
204  if( aSel.GetSize() > 1 )
205  return true;
206 
207  SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
208 
209  switch( item->Type() )
210  {
211  case SCH_MARKER_T:
212  case SCH_JUNCTION_T:
213  case SCH_NO_CONNECT_T:
214  case SCH_PIN_T:
215  return false;
216  case SCH_LINE_T:
217  return item->GetLayer() != LAYER_WIRE && item->GetLayer() != LAYER_BUS;
218  default:
219  return true;
220  }
221  };
222 
223  auto propertiesCondition =
224  [&]( const SELECTION& aSel )
225  {
226  if( aSel.GetSize() == 0 )
227  {
229  {
232 
233  if( ds && ds->HitTestDrawingSheetItems( getView(), (wxPoint) cursor ) )
234  return true;
235  }
236 
237  return false;
238  }
239 
240  SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
241  const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
242 
243  if( !firstItem || !eeSelection )
244  return false;
245 
246  switch( firstItem->Type() )
247  {
248  case SCH_SYMBOL_T:
249  case SCH_SHEET_T:
250  case SCH_SHEET_PIN_T:
251  case SCH_TEXT_T:
252  case SCH_LABEL_T:
253  case SCH_GLOBAL_LABEL_T:
254  case SCH_HIER_LABEL_T:
255  case SCH_FIELD_T:
256  case SCH_BITMAP_T:
257  return aSel.GetSize() == 1;
258 
259  case SCH_LINE_T:
261  return eeSelection->AllItemsHaveLineStroke();
262 
263  case SCH_JUNCTION_T:
264  return eeSelection->AreAllItemsIdentical();
265 
266  default:
267  return false;
268  }
269  };
270 
271  auto autoplaceCondition =
272  []( const SELECTION& aSel )
273  {
274  for( const EDA_ITEM* item : aSel )
275  {
276  if( item->IsType( EE_COLLECTOR::FieldOwners ) )
277  return true;
278  }
279 
280  return false;
281  };
282 
283  static KICAD_T allLabelTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
284 
285  static KICAD_T toLabelTypes[] = { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
286  auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toLabelTypes ) )
287  || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allLabelTypes ) );
288 
289  static KICAD_T toHLableTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_TEXT_T, EOT };
290  auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toHLableTypes ) )
291  || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allLabelTypes ) );
292 
293  static KICAD_T toGLableTypes[] = { SCH_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
294  auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toGLableTypes ) )
295  || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allLabelTypes ) );
296 
297  static KICAD_T toTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, EOT };
298  auto toTextlCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toTextTypes ) )
299  || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allLabelTypes ) );
300 
301  static KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT };
302  auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( entryTypes );
303 
304  auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
305 
306  //
307  // Add edit actions to the move tool menu
308  //
309  if( moveTool )
310  {
311  CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
312 
313  moveMenu.AddSeparator();
314  moveMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition );
315  moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition );
316  moveMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition );
317  moveMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition );
318 
319  moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
324 
325  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
326  symUnitMenu->SetTool( this );
327  m_menu.AddSubMenu( symUnitMenu );
328  moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
329 
330  moveMenu.AddSeparator();
334  moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
335 
336  moveMenu.AddSeparator();
337  moveMenu.AddItem( ACTIONS::selectAll, hasElements );
338  }
339 
340  //
341  // Add editing actions to the drawing tool menu
342  //
343  CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
344 
345  drawMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
346  drawMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
347  drawMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
348  drawMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
349 
350  drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
354  drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
356 
357  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
358  symUnitMenu2->SetTool( drawingTools );
359  drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 );
360  drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
361 
363 
364  drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
365  drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
366  drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
367  drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
368 
369  //
370  // Add editing actions to the selection tool menu
371  //
373 
374  selToolMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
375  selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
376  selToolMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
377  selToolMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
378 
379  selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
381  selToolMenu.AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
383  selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
385 
386  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
387  symUnitMenu3->SetTool( m_selectionTool );
388  m_selectionTool->GetToolMenu().AddSubMenu( symUnitMenu3 );
389  selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
390 
394 
395  selToolMenu.AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
396  selToolMenu.AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
397  selToolMenu.AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
398  selToolMenu.AddItem( EE_ACTIONS::toText, toTextlCondition, 200 );
399  selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
400 
401  selToolMenu.AddSeparator( 300 );
402  selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
403  selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
404  selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
405  selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
406  selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
407  selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
408 
409  selToolMenu.AddSeparator( 400 );
410  selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
411 
412 
413  return true;
414 }
415 
416 
418  SCH_TEXT_T,
419  SCH_LABEL_T,
422  SCH_FIELD_T,
423  SCH_SYMBOL_T,
425  SCH_SHEET_T,
426  SCH_BITMAP_T,
429  SCH_LINE_T,
432  EOT
433 };
434 
435 
436 int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
437 {
438  bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
440 
441  if( selection.GetSize() == 0 )
442  return 0;
443 
444  SCH_ITEM* head = nullptr;
445  int principalItemCount = 0; // User-selected items (as opposed to connected wires)
446  wxPoint rotPoint;
447  bool moving = false;
448  bool connections = false;
449 
450  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
451  {
452  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
453 
454  if( item->HasFlag( TEMP_SELECTED ) )
455  continue;
456 
457  principalItemCount++;
458 
459  if( !head )
460  head = item;
461  }
462 
463  if( head && head->IsMoving() )
464  moving = true;
465 
466  if( principalItemCount == 1 )
467  {
468  if( moving && selection.HasReferencePoint() )
469  rotPoint = (wxPoint) selection.GetReferencePoint();
470  else
471  rotPoint = head->GetPosition();
472 
473  if( !moving )
475 
476  switch( head->Type() )
477  {
478  case SCH_SYMBOL_T:
479  {
480  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
481 
482  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
483  symbol->Rotate( rotPoint );
484 
486  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
487 
488  break;
489  }
490 
491  case SCH_TEXT_T:
492  case SCH_LABEL_T:
493  case SCH_GLOBAL_LABEL_T:
494  case SCH_HIER_LABEL_T:
495  {
496  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
497  textItem->Rotate90( clockwise );
498  break;
499  }
500 
501  case SCH_SHEET_PIN_T:
502  {
503  // Rotate pin within parent sheet
504  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
505  SCH_SHEET* sheet = pin->GetParent();
506 
507  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
508  pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
509 
510  break;
511  }
512 
513  case SCH_LINE_T:
514  case SCH_BUS_BUS_ENTRY_T:
516  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
517  head->Rotate( rotPoint );
518 
519  break;
520 
521  case SCH_FIELD_T:
522  {
523  SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
524 
525  if( field->GetTextAngle() == TEXT_ANGLE_HORIZ )
526  field->SetTextAngle( TEXT_ANGLE_VERT );
527  else
528  field->SetTextAngle( TEXT_ANGLE_HORIZ );
529 
530  // Now that we're moving a field, they're no longer autoplaced.
531  static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
532 
533  break;
534  }
535 
536  case SCH_BITMAP_T:
537  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
538  head->Rotate( rotPoint );
539 
540  // The bitmap is cached in Opengl: clear the cache to redraw
542  break;
543 
544  case SCH_SHEET_T:
545  {
546  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
547  rotPoint = m_frame->GetNearestHalfGridPosition( sheet->GetRotationCenter() );
548 
549  // Rotate the sheet on itself. Sheets do not have an anchor point.
550  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
551  sheet->Rotate( rotPoint );
552 
553  break;
554  }
555 
556  default:
557  break;
558  }
559 
560  connections = head->IsConnectable();
561  m_frame->UpdateItem( head, false, true );
562  }
563  else
564  {
565  if( moving && selection.HasReferencePoint() )
566  rotPoint = (wxPoint) selection.GetReferencePoint();
567  else
568  rotPoint = m_frame->GetNearestHalfGridPosition( (wxPoint) selection.GetCenter() );
569  }
570 
571  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
572  {
573  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
574 
575  // We've already rotated the user selected item if there was only one. We're just
576  // here to rotate the ends of wires that were attached to it.
577  if( principalItemCount == 1 && !item->HasFlag( TEMP_SELECTED ) )
578  continue;
579 
580  if( !moving )
581  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
582 
583  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
584  {
585  if( item->Type() == SCH_LINE_T )
586  {
587  SCH_LINE* line = (SCH_LINE*) item;
588 
589  // If we are rotating more than one item, we do not have start/end
590  // points separately selected
591  if( item->HasFlag( STARTPOINT ) )
592  line->RotateStart( rotPoint );
593 
594  if( item->HasFlag( ENDPOINT ) )
595  line->RotateEnd( rotPoint );
596  }
597  else if( item->Type() == SCH_SHEET_PIN_T )
598  {
599  if( item->GetParent()->IsSelected() )
600  {
601  // parent will rotate us
602  }
603  else
604  {
605  // rotate within parent
606  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
607  SCH_SHEET* sheet = pin->GetParent();
608 
609  pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
610  }
611  }
612  else if( item->Type() == SCH_FIELD_T )
613  {
614  if( item->GetParent()->IsSelected() )
615  {
616  // parent will rotate us
617  }
618  else
619  {
620  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
621 
622  field->Rotate( rotPoint );
623 
624  if( field->GetTextAngle() == TEXT_ANGLE_HORIZ )
625  field->SetTextAngle( TEXT_ANGLE_VERT );
626  else
627  field->SetTextAngle( TEXT_ANGLE_HORIZ );
628 
629  // Now that we're moving a field, they're no longer autoplaced.
630  static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
631  }
632  }
633  else
634  {
635  item->Rotate( rotPoint );
636  }
637  }
638 
639  connections |= item->IsConnectable();
640  m_frame->UpdateItem( item, false, true );
641  updateItem( item, true );
642  }
643 
645 
646  if( moving )
647  {
649  }
650  else
651  {
652  if( selection.IsHover() )
654 
655  if( connections )
657 
658  m_frame->OnModify();
659  }
660 
661  return 0;
662 }
663 
664 
665 int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
666 {
668 
669  if( selection.GetSize() == 0 )
670  return 0;
671 
672  wxPoint mirrorPoint;
673  bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
674  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
675  bool connections = false;
676  bool moving = item->IsMoving();
677 
678  if( selection.GetSize() == 1 )
679  {
680  if( !moving )
682 
683  switch( item->Type() )
684  {
685  case SCH_SYMBOL_T:
686  {
687  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
688 
689  if( vertical )
690  symbol->SetOrientation( SYM_MIRROR_X );
691  else
692  symbol->SetOrientation( SYM_MIRROR_Y );
693 
695  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
696 
697  break;
698  }
699 
700  case SCH_TEXT_T:
701  case SCH_LABEL_T:
702  case SCH_GLOBAL_LABEL_T:
703  case SCH_HIER_LABEL_T:
704  {
705  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
706  textItem->MirrorSpinStyle( !vertical );
707  break;
708  }
709 
710  case SCH_SHEET_PIN_T:
711  {
712  // mirror within parent sheet
713  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
714  SCH_SHEET* sheet = pin->GetParent();
715 
716  if( vertical )
717  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
718  else
719  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
720 
721  break;
722  }
723 
724  case SCH_BUS_BUS_ENTRY_T:
726  if( vertical )
727  item->MirrorVertically( item->GetPosition().y );
728  else
729  item->MirrorHorizontally( item->GetPosition().x );
730  break;
731 
732  case SCH_FIELD_T:
733  {
734  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
735 
736  if( vertical )
738  else
740 
741  // Now that we're re-justifying a field, they're no longer autoplaced.
742  static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
743 
744  break;
745  }
746 
747  case SCH_BITMAP_T:
748  if( vertical )
749  item->MirrorVertically( item->GetPosition().y );
750  else
751  item->MirrorHorizontally( item->GetPosition().x );
752 
753  // The bitmap is cached in Opengl: clear the cache to redraw
755  break;
756 
757  case SCH_SHEET_T:
758  // Mirror the sheet on itself. Sheets do not have a anchor point.
759  mirrorPoint = m_frame->GetNearestHalfGridPosition( item->GetBoundingBox().Centre() );
760 
761  if( vertical )
762  item->MirrorVertically( mirrorPoint.y );
763  else
764  item->MirrorHorizontally( mirrorPoint.x );
765 
766  break;
767 
768  default:
769  break;
770  }
771 
772  connections = item->IsConnectable();
773  m_frame->UpdateItem( item, false, true );
774  }
775  else if( selection.GetSize() > 1 )
776  {
777  mirrorPoint = m_frame->GetNearestHalfGridPosition( (wxPoint)selection.GetCenter() );
778 
779  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
780  {
781  item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
782 
783  if( !moving )
784  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
785 
786  if( item->Type() == SCH_SHEET_PIN_T )
787  {
788  if( item->GetParent()->IsSelected() )
789  {
790  // parent will mirror us
791  }
792  else
793  {
794  // mirror within parent sheet
795  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
796  SCH_SHEET* sheet = pin->GetParent();
797 
798  if( vertical )
799  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
800  else
801  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
802  }
803  }
804  else
805  {
806  if( vertical )
807  item->MirrorVertically( mirrorPoint.y );
808  else
809  item->MirrorHorizontally( mirrorPoint.x );
810  }
811 
812  connections |= item->IsConnectable();
813  m_frame->UpdateItem( item, false, true );
814  }
815  }
816 
818 
819  // Update R-Tree for modified items
820  for( EDA_ITEM* selected : selection )
821  updateItem( selected, true );
822 
823  if( item->IsMoving() )
824  {
826  }
827  else
828  {
829  if( selection.IsHover() )
831 
832  if( connections )
834 
835  m_frame->OnModify();
836  }
837 
838  return 0;
839 }
840 
841 
843 {
844  SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
845 
846  if( !sourceItem )
847  return 0;
848 
850 
851  SCH_ITEM* newItem = sourceItem->Duplicate();
852  bool performDrag = false;
853 
854  // If cloning a symbol then put into 'move' mode.
855  if( newItem->Type() == SCH_SYMBOL_T )
856  {
857  wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( true );
858  newItem->Move( cursorPos - newItem->GetPosition() );
859  performDrag = true;
860  }
861  else
862  {
863  EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
864 
865  if( dynamic_cast<SCH_TEXT*>( newItem ) )
866  {
867  SCH_TEXT* text = static_cast<SCH_TEXT*>( newItem );
868 
869  // If incrementing tries to go below zero, tell user why the value is repeated
870 
871  if( !text->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
872  m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
873  }
874 
875  newItem->Move( wxPoint( Mils2iu( cfg->m_Drawing.default_repeat_offset_x ),
876  Mils2iu( cfg->m_Drawing.default_repeat_offset_y ) ) );
877  }
878 
879  newItem->SetFlags( IS_NEW );
880  m_frame->AddToScreen( newItem, m_frame->GetScreen() );
882 
883  // Symbols need to be handled by the move tool. The move tool will handle schematic
884  // cleanup routines
885  if( performDrag )
887 
888  newItem->ClearFlags();
889 
890  if( !performDrag && newItem->IsConnectable() )
891  {
892  EE_SELECTION new_sel;
893  new_sel.Add( newItem );
894 
896 
899  }
900 
901  m_frame->GetCanvas()->Refresh();
902  m_frame->OnModify();
903 
904  // Save newItem at the new position.
905  m_frame->SaveCopyForRepeatItem( newItem );
906 
907  return 0;
908 }
909 
910 
912 {
913  SCH_MARKER_T,
915  SCH_LINE_T,
918  SCH_TEXT_T,
919  SCH_LABEL_T,
923  SCH_SHEET_T,
925  SCH_SYMBOL_T,
926  SCH_BITMAP_T,
927  EOT
928 };
929 
930 
932 {
933  SCH_SCREEN* screen = m_frame->GetScreen();
935  bool appendToUndo = false;
936  std::vector<wxPoint> pts;
937 
938  if( items.empty() )
939  return 0;
940 
941  // Don't leave a freed pointer in the selection
943 
944  for( EDA_ITEM* item : items )
945  item->ClearFlags( STRUCT_DELETED );
946 
947  for( EDA_ITEM* item : items )
948  {
949  SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
950 
951  if( !sch_item )
952  continue;
953 
954  if( sch_item->IsConnectable() )
955  {
956  std::vector<wxPoint> tmp_pts = sch_item->GetConnectionPoints();
957  pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
958  }
959 
960  if( sch_item->Type() == SCH_JUNCTION_T )
961  {
962  sch_item->SetFlags( STRUCT_DELETED );
963  // clean up junctions at the end
964  }
965  else if( sch_item->Type() == SCH_SHEET_PIN_T )
966  {
967  SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
968  SCH_SHEET* sheet = pin->GetParent();
969 
970  if( !alg::contains( items, sheet ) )
971  {
972  pin->SetFlags( STRUCT_DELETED );
973  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
974  appendToUndo = true;
975 
976  updateItem( pin, false );
977 
978  sheet->RemovePin( pin );
979  }
980  }
981  else
982  {
983  sch_item->SetFlags( STRUCT_DELETED );
984  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
985  appendToUndo = true;
986 
987  updateItem( sch_item, false );
988 
989  m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
990 
991  if( sch_item->Type() == SCH_SHEET_T )
993  }
994  }
995 
996  for( const wxPoint& point : pts )
997  {
998  SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
999 
1000  if( !junction )
1001  continue;
1002 
1003  if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1004  m_frame->DeleteJunction( junction, appendToUndo );
1005  }
1006 
1008 
1009  m_frame->GetCanvas()->Refresh();
1010  m_frame->OnModify();
1011 
1012  return 0;
1013 }
1014 
1015 
1016 #define HITTEST_THRESHOLD_PIXELS 5
1017 
1018 
1020 {
1021  std::string tool = aEvent.GetCommandStr().get();
1022  PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
1023 
1025  m_pickerItem = nullptr;
1026 
1027  // Deactivate other tools; particularly important if another PICKER is currently running
1028  Activate();
1029 
1030  picker->SetCursor( KICURSOR::REMOVE );
1031  picker->SetSnapping( false );
1032 
1033  picker->SetClickHandler(
1034  [this]( const VECTOR2D& aPosition ) -> bool
1035  {
1036  if( m_pickerItem )
1037  {
1039  selectionTool->UnbrightenItem( m_pickerItem );
1040  selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1042  m_pickerItem = nullptr;
1043  }
1044 
1045  return true;
1046  } );
1047 
1048  picker->SetMotionHandler(
1049  [this]( const VECTOR2D& aPos )
1050  {
1051  EE_COLLECTOR collector;
1052  collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1053  collector.Collect( m_frame->GetScreen(), deletableItems, (wxPoint) aPos );
1054 
1056  selectionTool->GuessSelectionCandidates( collector, aPos );
1057 
1058  EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1059 
1060  if( m_pickerItem != item )
1061  {
1062  if( m_pickerItem )
1063  selectionTool->UnbrightenItem( m_pickerItem );
1064 
1065  m_pickerItem = item;
1066 
1067  if( m_pickerItem )
1068  selectionTool->BrightenItem( m_pickerItem );
1069  }
1070  } );
1071 
1072  picker->SetFinalizeHandler(
1073  [this]( const int& aFinalState )
1074  {
1075  if( m_pickerItem )
1077 
1078  // Wake the selection tool after exiting to ensure the cursor gets updated
1080  } );
1081 
1082  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1083 
1084  return 0;
1085 }
1086 
1087 
1089 {
1090  // Save old symbol in undo list if not already in edit, or moving.
1091  if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1093 
1094  KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1095  wxString caption;
1096 
1097  // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1098  if( parentType == SCH_SYMBOL_T && aField->GetId() < MANDATORY_FIELDS )
1099  caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1100  else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
1101  caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1102  else
1103  caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1104 
1105  DIALOG_SCH_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1106 
1107  // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1108  if( dlg.ShowQuasiModal() != wxID_OK )
1109  return;
1110 
1111  dlg.UpdateField( aField, &m_frame->GetCurrentSheet() );
1112 
1113  if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1114  static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1115 
1116  m_frame->UpdateItem( aField, false, true );
1117  m_frame->OnModify();
1118 
1119  // This must go after OnModify() so that the connectivity graph will have been updated.
1121 }
1122 
1123 
1125 {
1126  static KICAD_T Nothing[] = { EOT };
1127  static KICAD_T CmpOrReference[] = { SCH_FIELD_LOCATE_REFERENCE_T, SCH_SYMBOL_T, EOT };
1128  static KICAD_T CmpOrValue[] = { SCH_FIELD_LOCATE_VALUE_T, SCH_SYMBOL_T, EOT };
1129  static KICAD_T CmpOrFootprint[] = { SCH_FIELD_LOCATE_FOOTPRINT_T, SCH_SYMBOL_T, EOT };
1130 
1131  KICAD_T* filter = Nothing;
1132 
1133  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1134  filter = CmpOrReference;
1135  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1136  filter = CmpOrValue;
1137  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1138  filter = CmpOrFootprint;
1139 
1141 
1142  if( selection.Size() != 1 )
1143  return 0;
1144 
1145  bool clearSelection = selection.IsHover();
1146  EDA_ITEM* item = selection.Front();
1147 
1148  if( item->Type() == SCH_SYMBOL_T )
1149  {
1150  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1151 
1152  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1153  editFieldText( symbol->GetField( REFERENCE_FIELD ) );
1154  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1155  editFieldText( symbol->GetField( VALUE_FIELD ) );
1156  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1157  editFieldText( symbol->GetField( FOOTPRINT_FIELD ) );
1158  }
1159  else if( item->Type() == SCH_FIELD_T )
1160  {
1161  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1162 
1163  editFieldText( field );
1164 
1165  if( !field->IsVisible() )
1166  clearSelection = true;
1167  }
1168 
1169  if( clearSelection )
1171 
1172  return 0;
1173 }
1174 
1175 
1177 {
1179 
1180  if( selection.Empty() )
1181  return 0;
1182 
1183  SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1184  bool moving = head && head->IsMoving();
1185 
1186  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1187  {
1188  SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1189 
1190  if( !moving && !sch_item->IsNew() )
1191  saveCopyInUndoList( sch_item, UNDO_REDO::CHANGED, ii > 0 );
1192 
1193  if( sch_item->IsType( EE_COLLECTOR::FieldOwners ) )
1194  sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1195 
1196  updateItem( sch_item, true );
1197  }
1198 
1200 
1201  if( moving )
1202  {
1204  }
1205  else
1206  {
1207  if( selection.IsHover() )
1209 
1210  m_frame->OnModify();
1211  }
1212 
1213  return 0;
1214 }
1215 
1216 
1218 {
1219  SCH_SYMBOL* selectedSymbol = nullptr;
1221 
1222  if( !selection.Empty() )
1223  selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1224 
1226 
1227  if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1228  || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1229  {
1231  }
1232 
1233  DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1234 
1235  dlg.ShowQuasiModal();
1236 
1237  return 0;
1238 }
1239 
1240 
1242 {
1244 
1245  if( selection.Empty() )
1246  return 0;
1247 
1248  SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1249 
1251  && symbol->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1252  {
1253  return 0;
1254  }
1255 
1257  && symbol->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
1258  {
1259  return 0;
1260  }
1261 
1262  if( !symbol->IsNew() )
1264 
1265  m_frame->ConvertPart( symbol );
1266 
1267  if( symbol->IsNew() )
1269 
1270  if( selection.IsHover() )
1272 
1273  return 0;
1274 }
1275 
1276 
1278 {
1280  bool clearSelection = selection.IsHover();
1281 
1282  if( selection.Empty() )
1283  {
1285  {
1287  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1288 
1289  if( ds && ds->HitTestDrawingSheetItems( getView(), (wxPoint) cursorPos ) )
1291  }
1292 
1293  return 0;
1294  }
1295 
1296  EDA_ITEM* item = selection.Front();
1297 
1298  switch( item->Type() )
1299  {
1300  case SCH_LINE_T:
1301  case SCH_BUS_WIRE_ENTRY_T:
1302  if( !selection.AllItemsHaveLineStroke() )
1303  return 0;
1304 
1305  break;
1306 
1307  case SCH_JUNCTION_T:
1308  if( !selection.AreAllItemsIdentical() )
1309  return 0;
1310 
1311  break;
1312 
1313  default:
1314  if( selection.Size() > 1 )
1315  return 0;
1316 
1317  break;
1318  }
1319 
1320  auto doTextAndLabelProps =
1321  [&]( SCH_TEXT* aText )
1322  {
1324 
1325  // Must be quasi modal for syntax help
1326  if( dlg.ShowQuasiModal() == wxID_OK )
1327  {
1329  m_frame->OnModify();
1330  }
1331  };
1332 
1333  switch( item->Type() )
1334  {
1335  case SCH_SYMBOL_T:
1336  {
1337  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1338  DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1339 
1340  // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1341  // frame. Therefore this dialog as a modal frame parent, MUST be run under
1342  // quasimodal mode for the quasimodal frame support to work. So don't use
1343  // the QUASIMODAL macros here.
1344  int retval = symbolPropsDialog.ShowQuasiModal();
1345 
1346  if( retval == SYMBOL_PROPS_EDIT_OK )
1347  {
1349  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
1350 
1352  m_frame->OnModify();
1353  }
1354  else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1355  {
1357  true );
1358 
1359  editor->LoadSymbolFromSchematic( symbol );
1360 
1361  editor->Show( true );
1362  editor->Raise();
1363  }
1364  else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1365  {
1367  true );
1368 
1369  editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
1370 
1371  editor->Show( true );
1372  editor->Raise();
1373  }
1374  else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1375  {
1377  dlg.ShowQuasiModal();
1378  }
1379  else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1380  {
1382  dlg.ShowQuasiModal();
1383  }
1384  }
1385  break;
1386 
1387  case SCH_SHEET_T:
1388  {
1389  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1390  bool doClearAnnotation;
1391  bool doRefresh = false;
1392 
1393  // Keep track of existing sheet paths. EditSheet() can modify this list.
1394  // Note that we use the validity checking/repairing version here just to make sure
1395  // we've got a valid hierarchy to begin with.
1396  SCH_SHEET_LIST initial_sheetpathList( &m_frame->Schematic().Root(), true );
1397 
1398  doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1399  &doClearAnnotation );
1400 
1401  // If the sheet file is changed and new sheet contents are loaded then we have to
1402  // clear the annotations on the new content (as it may have been set from some other
1403  // sheet path reference)
1404  if( doClearAnnotation )
1405  {
1406  SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1407  // We clear annotation of new sheet paths here:
1408  screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
1409  // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1410  // path, but symbols managed by its sheet path must have their annotation cleared
1411  // because they are new:
1413  }
1414 
1415  if( doRefresh )
1416  {
1418  m_frame->GetCanvas()->Refresh();
1420  }
1421 
1422  break;
1423  }
1424 
1425  case SCH_SHEET_PIN_T:
1426  {
1427  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1429 
1430  // QuasiModal required for help dialog
1431  if( dlg.ShowQuasiModal() == wxID_OK )
1432  {
1434  m_frame->OnModify();
1435  }
1436  }
1437  break;
1438 
1439  case SCH_TEXT_T:
1440  case SCH_LABEL_T:
1441  case SCH_GLOBAL_LABEL_T:
1442  case SCH_HIER_LABEL_T:
1443  doTextAndLabelProps( static_cast<SCH_TEXT*>( item ) );
1444  break;
1445 
1446  case SCH_FIELD_T:
1447  {
1448  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1449  EDA_ITEM* parent = field->GetParent();
1450 
1451  if( parent->Type() == SCH_GLOBAL_LABEL_T )
1452  doTextAndLabelProps( static_cast<SCH_TEXT*>( parent ) );
1453  else
1454  editFieldText( field );
1455 
1456  if( !field->IsVisible() )
1457  clearSelection = true;
1458  }
1459  break;
1460 
1461  case SCH_BITMAP_T:
1462  {
1463  SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( item );
1464  DIALOG_IMAGE_EDITOR dlg( m_frame, bitmap->GetImage() );
1465 
1466  if( dlg.ShowModal() == wxID_OK )
1467  {
1468  // save old image in undo list if not already in edit
1469  if( bitmap->GetEditFlags() == 0 )
1471 
1472  dlg.TransferToImage( bitmap->GetImage() );
1473 
1474  // The bitmap is cached in Opengl: clear the cache in case it has become invalid
1475  getView()->RecacheAllItems();
1477  m_frame->OnModify();
1478  }
1479  }
1480  break;
1481 
1482  case SCH_LINE_T:
1483  case SCH_BUS_WIRE_ENTRY_T:
1484  {
1485  std::deque<SCH_ITEM*> strokeItems;
1486 
1487  for( EDA_ITEM* selItem : selection.Items() )
1488  {
1489  SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( selItem );
1490 
1491  if( schItem && schItem->HasLineStroke() )
1492  strokeItems.push_back( schItem );
1493  else
1494  return 0;
1495  }
1496 
1497  DIALOG_LINE_WIRE_BUS_PROPERTIES dlg( m_frame, strokeItems );
1498 
1499  if( dlg.ShowModal() == wxID_OK )
1500  {
1502  m_frame->OnModify();
1503  }
1504  }
1505  break;
1506 
1507  case SCH_JUNCTION_T:
1508  {
1509  std::deque<SCH_JUNCTION*> junctions;
1510 
1511  for( EDA_ITEM* selItem : selection.Items() )
1512  {
1513  SCH_JUNCTION* junction = dynamic_cast<SCH_JUNCTION*>( selItem );
1514 
1515  wxCHECK( junction, 0 );
1516 
1517  junctions.push_back( junction );
1518  }
1519 
1520  DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1521 
1522  if( dlg.ShowModal() == wxID_OK )
1523  {
1525  m_frame->OnModify();
1526  }
1527  }
1528  break;
1529 
1530  case SCH_MARKER_T: // These items have no properties to edit
1531  case SCH_NO_CONNECT_T:
1532  break;
1533 
1534  default: // Unexpected item
1535  wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + item->GetClass() );
1536  }
1537 
1538  updateItem( item, true );
1539 
1540  if( clearSelection )
1542 
1543  return 0;
1544 }
1545 
1546 
1548 {
1549  KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
1551  EE_SELECTION selection = m_selectionTool->RequestSelection( allTextTypes );
1552 
1553  for( unsigned int i = 0; i < selection.GetSize(); ++i )
1554  {
1555  SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( selection.GetItem( i ) );
1556 
1557  if( text && text->Type() != convertTo )
1558  {
1559  bool selected = text->IsSelected();
1560  SCH_TEXT* newtext = nullptr;
1561  const wxPoint& position = text->GetPosition();
1562  LABEL_SPIN_STYLE orientation = text->GetLabelSpinStyle();
1563  wxString txt = UnescapeString( text->GetText() );
1564 
1565  // There can be characters in a SCH_TEXT object that can break labels so we have to
1566  // fix them here.
1567  if( text->Type() == SCH_TEXT_T )
1568  {
1569  txt.Replace( "\n", "_" );
1570  txt.Replace( "\r", "_" );
1571  txt.Replace( "\t", "_" );
1572  txt.Replace( " ", "_" );
1573  }
1574 
1575  // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
1576  if( convertTo != SCH_TEXT_T )
1577  txt = EscapeString( txt, CTX_NETNAME );
1578 
1579  switch( convertTo )
1580  {
1581  case SCH_LABEL_T: newtext = new SCH_LABEL( position, txt ); break;
1582  case SCH_GLOBAL_LABEL_T: newtext = new SCH_GLOBALLABEL( position, txt ); break;
1583  case SCH_HIER_LABEL_T: newtext = new SCH_HIERLABEL( position, txt ); break;
1584  case SCH_TEXT_T: newtext = new SCH_TEXT( position, txt ); break;
1585 
1586  default:
1587  wxFAIL_MSG( wxString::Format( "Invalid text type: %d.", convertTo ) );
1588  return 0;
1589  }
1590 
1591  // Copy the old text item settings to the new one. Justifications are not copied
1592  // because they are not used in labels. Justifications will be set to default value
1593  // in the new text item type.
1594  //
1595  newtext->SetFlags( text->GetEditFlags() );
1596  newtext->SetShape( text->GetShape() );
1597  newtext->SetLabelSpinStyle( orientation );
1598  newtext->SetTextSize( text->GetTextSize() );
1599  newtext->SetTextThickness( text->GetTextThickness() );
1600  newtext->SetItalic( text->IsItalic() );
1601  newtext->SetBold( text->IsBold() );
1602  newtext->SetIsDangling( text->IsDangling() );
1603 
1604  if( selected )
1606 
1607  if( !text->IsNew() )
1608  {
1610  saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
1611 
1613  m_frame->AddToScreen( newtext, m_frame->GetScreen() );
1614 
1615  if( convertTo == SCH_GLOBAL_LABEL_T )
1616  static_cast<SCH_GLOBALLABEL*>( newtext )->UpdateIntersheetRefProps();
1617  }
1618 
1619  if( selected )
1620  m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
1621 
1622  // Otherwise, pointer is owned by the undo stack
1623  if( text->IsNew() )
1624  delete text;
1625 
1626  if( convertTo == SCH_TEXT_T )
1627  {
1628  if( newtext->IsDangling() )
1629  {
1630  newtext->SetIsDangling( false );
1631  getView()->Update( newtext, KIGFX::REPAINT );
1632  }
1633  }
1634  else
1635  {
1637  }
1638 
1639  m_frame->OnModify();
1640  }
1641  }
1642 
1643  if( selection.IsHover() )
1645 
1646  return 0;
1647 }
1648 
1649 
1651 {
1652  wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
1654 
1655  std::vector<SCH_LINE*> lines;
1656 
1657  for( EDA_ITEM* item : selection )
1658  {
1659  if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
1660  {
1661  if( !line->IsEndPoint( cursorPos ) )
1662  lines.push_back( line );
1663  }
1664  }
1665 
1667  m_frame->StartNewUndo();
1668 
1669  for( SCH_LINE* line : lines )
1670  m_frame->BreakSegment( line, cursorPos );
1671 
1672  if( !lines.empty() )
1673  {
1674  if( m_frame->GetScreen()->IsExplicitJunctionNeeded( cursorPos ) )
1675  m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false );
1676 
1678 
1679  m_frame->OnModify();
1680  m_frame->GetCanvas()->Refresh();
1681 
1683  }
1684 
1685  return 0;
1686 }
1687 
1688 
1690 {
1692  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1693 
1694  if( !sheet || !sheet->HasUndefinedPins() )
1695  return 0;
1696 
1697  if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
1698  return 0;
1699 
1701 
1702  sheet->CleanupSheet();
1703 
1704  updateItem( sheet, true );
1705  m_frame->OnModify();
1706 
1707  if( selection.IsHover() )
1709 
1710  return 0;
1711 }
1712 
1713 
1715 {
1717 
1718  if( selection.GetSize() > 1 )
1719  return 0;
1720 
1721  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1722 
1723  SCH_SHEET_PATH instance = m_frame->GetCurrentSheet();
1724 
1725  SCH_SCREEN* screen;
1726 
1727  if( sheet )
1728  {
1729  // When changing the page number of a selected sheet, the current screen owns the sheet.
1730  screen = m_frame->GetScreen();
1731 
1732  instance.push_back( sheet );
1733  }
1734  else
1735  {
1736  SCH_SHEET_PATH prevInstance = instance;
1737 
1738  // When change the page number in the screen, the previous screen owns the sheet.
1739  if( prevInstance.size() )
1740  {
1741  prevInstance.pop_back();
1742  screen = prevInstance.LastScreen();
1743  }
1744  else
1745  {
1746  // The root sheet and root screen are effectively the same thing.
1747  screen = m_frame->GetScreen();
1748  }
1749 
1750  sheet = m_frame->GetCurrentSheet().Last();
1751  }
1752 
1753  wxString msg;
1754  wxString sheetPath = instance.PathHumanReadable( false );
1755  wxString pageNumber = instance.GetPageNumber();
1756 
1757  msg.Printf( _( "Enter page number for sheet path%s" ),
1758  ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
1759 
1760  wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
1761 
1762  dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
1763 
1764  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
1765  return 0;
1766 
1767  m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
1768 
1769  instance.SetPageNumber( dlg.GetValue() );
1770 
1771  if( instance == m_frame->GetCurrentSheet() )
1772  {
1773  m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
1775  }
1776 
1777  m_frame->OnModify();
1778 
1779  return 0;
1780 }
1781 
1782 
1784 {
1788  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorV.MakeEvent() );
1789  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorH.MakeEvent() );
1790  Go( &SCH_EDIT_TOOL::DoDelete, ACTIONS::doDelete.MakeEvent() );
1792 
1809 
1812 
1816 }
Field Reference of part, i.e. "IC21".
static TOOL_ACTION editPageNumber
Definition: ee_actions.h:154
bool IsDangling() const override
Definition: sch_text.h:230
VECTOR2I GetReferencePoint() const
Definition: selection.h:184
bool empty() const
Definition: sch_rtree.h:177
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Definition: eda_text.h:71
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
static TOOL_ACTION properties
Definition: ee_actions.h:120
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
bool IsCurrentTool(const TOOL_ACTION &aAction) const
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:163
#define HITTEST_THRESHOLD_PIXELS
bool IsExplicitJunction(const wxPoint &aPosition) const
Indicates that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:413
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
int m_Threshold
Definition: collector.h:241
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
virtual bool IsConnectable() const
Definition: sch_item.h:349
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:71
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:82
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:220
bool IsHover() const
Definition: selection.h:74
#define STARTPOINT
When a line is selected, these flags indicate which.
void SetPageNumber(const wxString &aPageNumber)
Definition: base_screen.h:79
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:150
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:125
virtual std::vector< wxPoint > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:364
static TOOL_ACTION breakBus
Definition: ee_actions.h:134
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
static TOOL_ACTION pageSettings
Definition: actions.h:56
static SELECTION_CONDITION SingleSymbol
void RecalculateConnections(SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
bool IsSelected() const
Definition: eda_item.h:122
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:677
#define IS_NEW
New item, just created.
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
Definition: sch_sheet.h:47
void StartNewUndo()
Create a new, blank stack for future Undo commands to be pushed to.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:48
This file is part of the common library.
static TOOL_ACTION doDelete
Definition: actions.h:72
void ConvertPart(SCH_SYMBOL *aSymbol)
Definition: getpart.cpp:242
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.).
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:73
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
void Collect(SCH_SCREEN *aScreen, const KICAD_T aFilterList[], const wxPoint &aPos, int aUnit=0, int aConvert=0)
Scan a EDA_ITEM using this class's Inspector method which does the collection.
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:436
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Create a functor that tests if the selected items are only of given types.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
wxString PathHumanReadable(bool aUseShortRootName=true) const
Return the sheet path in a human readable form made from the sheet names.
bool IsMoving() const
Definition: eda_item.h:119
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
int Rotate(const TOOL_EVENT &aEvent)
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:87
void SetItalic(bool isItalic)
Definition: eda_text.h:200
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:148
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1385
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:155
int EditPageNumber(const TOOL_EVENT &aEvent)
int BreakWire(const TOOL_EVENT &aEvent)
virtual void MirrorVertically(int aCenter)=0
Mirror item vertically about aCenter.
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:152
TOOL_MENU & GetToolMenu()
double GetTextAngle() const
Definition: eda_text.h:195
int GetId() const
Definition: sch_field.h:113
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:388
static TOOL_ACTION toText
Definition: ee_actions.h:132
static const KICAD_T FieldOwners[]
Definition: ee_collectors.h:48
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:124
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:383
wxPoint GetNearestHalfGridPosition(const wxPoint &aPosition) const
Return the nearest aGridSize / 2 location to aPosition.
Schematic editor (Eeschema) main window.
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const wxPoint &aPosition)
int Properties(const TOOL_EVENT &aEvent)
bool AreAllItemsIdentical() const
Checks if all items in the selection are the same KICAD_T type.
Definition: selection.cpp:160
void OnPageSettingsChange() override
Called when modifying the page settings.
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:147
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:102
#define ENDPOINT
ends. (Used to support dragging.)
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:480
virtual wxPoint GetPosition() const
Definition: eda_item.h:251
static const KICAD_T SheetsOnly[]
Definition: ee_collectors.h:46
static TOOL_ACTION mirrorH
Definition: ee_actions.h:119
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void SetIsDangling(bool aIsDangling)
Definition: sch_text.h:231
void update() override
Update menu state stub.
virtual void Rotate(const wxPoint &aCenter)=0
Rotate the item around aCenter 90 degrees in the clockwise direction.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
Handle editing a single symbol field in the schematic editor.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:127
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
Dialog to update or change schematic library symbols.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void ShowInfoBarWarning(const wxString &aWarningMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and a warning icon on the left ...
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:205
void GuessSelectionCandidates(EE_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
static TOOL_ACTION breakWire
Definition: ee_actions.h:133
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:770
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:164
static TOOL_ACTION mirrorV
Definition: ee_actions.h:118
static TOOL_ACTION rotateCW
Definition: ee_actions.h:116
bool IsNew() const
Definition: eda_item.h:118
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:88
void pop_back()
Forwarded method from std::vector.
SCH_JUNCTION * AddJunction(SCH_SCREEN *aScreen, const wxPoint &aPos, bool aAppendToUndo, bool aFinal=true)
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:60
static TOOL_ACTION pickerTool
Definition: actions.h:155
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:66
EE_SELECTION & GetSelection()
Return the set of currently selected items.
EESCHEMA_SETTINGS * eeconfig() const
EE_SELECTION & RequestSelection(const KICAD_T *aFilterList=EE_COLLECTOR::AllItems)
Return either an existing selection (filtered), or the selection at the current cursor if the existin...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
static SELECTION_CONDITION SingleDeMorganSymbol
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:82
static TOOL_ACTION copy
Definition: actions.h:67
void editFieldText(SCH_FIELD *aField)
Set up handlers for various events.
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:191
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:117
void BrightenItem(EDA_ITEM *aItem)
int GlobalEdit(const TOOL_EVENT &aEvent)
Delete the selected items, or the item under the cursor.
static TOOL_ACTION editFootprint
Definition: ee_actions.h:123
AUTOPLACE_FIELDS m_AutoplaceFields
Item needs to be redrawn.
Definition: view_item.h:52
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:219
Field Value of part, i.e. "3.3K".
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:626
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:85
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
BITMAP_BASE * GetImage() const
Definition: sch_bitmap.h:54
size_t size() const
Forwarded method from std::vector.
void saveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aType, bool aAppend=false)
Definition: ee_tool_base.h:134
wxString TitleCaps(const wxString &aString)
Capitalize the first letter in each word.
virtual bool IsVisible() const
Definition: eda_text.h:207
int ShowQuasiModal()
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:432
wxString GetPageNumber() const
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:442
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:223
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:90
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Generic, UI-independent tool event.
Definition: tool_event.h:152
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:149
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:82
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:453
int AutoplaceFields(const TOOL_EVENT &aEvent)
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:115
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:342
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:109
static TOOL_ACTION cut
Definition: actions.h:66
SCHEMATIC & Schematic() const
void UpdateHierarchyNavigator(bool aForceUpdate=false)
Run the Hierarchy Navigator dialog.
EDA_ITEM * GetParent() const
Definition: eda_item.h:114
const KICAD_T rotatableItems[]
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false)
Mark an item for refresh.
const EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:605
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:153
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:177
virtual bool IsType(const KICAD_T aScanTypes[]) const
Check whether the item is one of the listed types.
Definition: eda_item.h:182
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:362
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
bool DisableGridSnapping() const
Definition: tool_event.h:341
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:157
bool Init() override
Init() is called once upon a registration of the tool.
static TOOL_ACTION addNeededJunctions
Definition: ee_actions.h:75
int CleanupSheetPins(const TOOL_EVENT &aEvent)
static SELECTION_CONDITION SingleMultiUnitSymbol
virtual void MirrorHorizontally(int aCenter)=0
Mirror item horizontally about aCenter.
static TOOL_ACTION editTextAndGraphics
Definition: ee_actions.h:192
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:502
int DeleteItemCursor(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:126
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:40
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:562
wxString UnescapeString(const wxString &aSource)
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:98
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:62
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
Definition: ee_tool_base.h:103
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:326
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
bool AllItemsHaveLineStroke() const
Checks if all items in the selection support line strokes.
int Mirror(const TOOL_EVENT &aEvent)
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:312
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
static TOOL_ACTION pasteSpecial
Definition: actions.h:69
EDA_TEXT_VJUSTIFY_T
Definition: eda_text.h:89
EDA_ITEM * m_pickerItem
Definition: sch_edit_tool.h:87
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:88
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:259
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:71
int RepeatDrawItem(const TOOL_EVENT &aEvent)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
bool IsExplicitJunctionNeeded(const wxPoint &aPosition) const
Indicates that a junction dot is necessary at the given location, and does not yet exist.
Definition: sch_screen.cpp:423
static TOOL_ACTION placeLabel
Definition: ee_actions.h:85
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:460
static bool IsDrawingLineWireOrBus(const SELECTION &aSelection)
static TOOL_ACTION editValue
Definition: ee_actions.h:122
static KICAD_T deletableItems[]
bool BreakSegment(SCH_LINE *aSegment, const wxPoint &aPoint, SCH_LINE **aNewSegment=nullptr, SCH_SCREEN *aScreen=nullptr)
Break a single segment into two at the specified point.
SCH_SHEET & Root() const
Definition: schematic.h:92
SCH_ITEM * GetRepeatItem() const
Return the item which is to be repeated with the insert key.
bool HasReferencePoint() const
Definition: selection.h:179
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:87
virtual wxString GetClass() const =0
Return the class name.
see class PGM_BASE
Schematic symbol object.
Definition: sch_symbol.h:78
int AddItemToSel(const TOOL_EVENT &aEvent)
SCH_SCREEN * LastScreen()
#define TEMP_SELECTED
flag indicating that the structure has already selected
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:53
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend)
Create a copy of the current schematic item, and put it in the undo list.
TOOL_MANAGER * getToolManager() const
static TOOL_ACTION drag
Definition: ee_actions.h:114
void DeleteJunction(SCH_ITEM *aItem, bool aAppend=false)
Removes a given junction and heals any wire segments under the junction.
void AddSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:52
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
Definition: sch_field.cpp:678
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Create a functor that tests if the selected items are only of given type.
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
int EditField(const TOOL_EVENT &aEvent)
void Clear()
Remove all the entries from the menu (as well as its title).
int Size() const
Returns the number of selected parts.
Definition: selection.h:104
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:146
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
wxPoint Centre() const
Definition: eda_rect.h:55
int ChangeSymbols(const TOOL_EVENT &aEvent)
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:458
void Activate()
Run the tool.
void RotateEnd(const wxPoint &aCenter)
Definition: sch_line.cpp:464
wxPoint GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:637
static SELECTION_CONDITION SingleSymbolOrPower
SCH_SHEET_PATH & GetCurrentSheet() const
static TOOL_ACTION deleteTool
Definition: actions.h:73
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the symbols in aSheetPath on the screen.
Definition: sch_screen.cpp:984
static const KICAD_T SymbolsOnly[]
Definition: ee_collectors.h:45
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:161
static TOOL_ACTION move
Definition: ee_actions.h:113
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:49
static TOOL_ACTION toLabel
Definition: ee_actions.h:129
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
void SetSnapping(bool aSnap)
Definition: picker_tool.h:64
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:321
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:98
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
#define TEXT_ANGLE_VERT
Definition: eda_text.h:72
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:188
static TOOL_ACTION toHLabel
Definition: ee_actions.h:130
void UpdateField(SCH_FIELD *aField, SCH_SHEET_PATH *aSheetPath)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
virtual const EDA_RECT GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:75
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
static TOOL_ACTION editReference
Definition: ee_actions.h:121
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
int GetUnit() const
Definition: sch_symbol.h:195
virtual void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:330
void RotateStart(const wxPoint &aCenter)
Definition: sch_line.cpp:458
const wxPoint GetCenter() const
Definition: eda_rect.h:104
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:86
int DoDelete(const TOOL_EVENT &aEvent)
Run the deletion tool.
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
void SetBold(bool aBold)
Definition: eda_text.h:203
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
int GetConvert() const
Definition: sch_symbol.h:223
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
static TOOL_ACTION selectAll
Definition: actions.h:70
static TOOL_ACTION toGLabel
Definition: ee_actions.h:131
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:323
int ConvertDeMorgan(const TOOL_EVENT &aEvent)
static TOOL_ACTION paste
Definition: actions.h:68
static const KICAD_T EditableItems[]
Definition: ee_collectors.h:43
static TOOL_ACTION duplicate
Definition: actions.h:71
int ChangeTextType(const TOOL_EVENT &aEvent)
Change a text type to another one.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:593
static TOOL_ACTION refreshPreview
Definition: actions.h:106
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:145
Dialog used to edit SCH_SYMBOL objects in a schematic.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1570
static const KICAD_T WiresOnly[]
Definition: ee_collectors.h:47
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:147
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:405
Field Name Module PCB, i.e. "16DIP300".
The symbol library editor main window.
virtual void Move(const wxPoint &aMoveVector)=0
Move the item by aMoveVector to a new position.