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 <kicad_string.h>
38 #include <sch_item.h>
39 #include <sch_symbol.h>
40 #include <sch_sheet.h>
41 #include <sch_text.h>
42 #include <sch_bitmap.h>
43 #include <sch_view.h>
44 #include <sch_line.h>
45 #include <sch_bus_entry.h>
46 #include <sch_junction.h>
47 #include <sch_edit_frame.h>
48 #include <schematic.h>
51 #include <eeschema_id.h>
52 #include <status_popup.h>
53 #include <wx/gdicmn.h>
61 #include "sch_drawing_tools.h"
62 #include <math/util.h> // for KiROUND
63 #include <pgm_base.h>
65 #include <symbol_editor_settings.h>
67 #include <core/kicad_algo.h>
68 
69 
71 {
72 public:
74  ACTION_MENU( true )
75  {
77  SetTitle( _( "Symbol Unit" ) );
78  }
79 
80 protected:
81  ACTION_MENU* create() const override
82  {
83  return new SYMBOL_UNIT_MENU();
84  }
85 
86 private:
87  void update() override
88  {
90  EE_SELECTION& selection = selTool->GetSelection();
91  SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( selection.Front() );
92 
93  Clear();
94 
95  if( !component )
96  {
97  Append( ID_POPUP_SCH_UNFOLD_BUS, _( "no symbol selected" ), wxEmptyString );
98  Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
99  return;
100  }
101 
102  int unit = component->GetUnit();
103 
104  if( !component->GetPartRef() || component->GetPartRef()->GetUnitCount() < 2 )
105  {
106  Append( ID_POPUP_SCH_UNFOLD_BUS, _( "symbol is not multi-unit" ), wxEmptyString );
107  Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
108  return;
109  }
110 
111  for( int ii = 0; ii < component->GetPartRef()->GetUnitCount(); ii++ )
112  {
113  wxString num_unit;
114  num_unit.Printf( _( "Unit %s" ), LIB_PART::SubReference( ii + 1, false ) );
115 
116  wxMenuItem * item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
117  wxITEM_CHECK );
118  if( unit == ii + 1 )
119  item->Check(true);
120 
121  // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_CMP_MAX
122  // See eeschema_id to modify this value.
124  break; // We have used all IDs for these submenus
125  }
126  }
127 };
128 
129 
131  EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
132 {
133  m_pickerItem = nullptr;
134 }
135 
136 
138 
140 {
142 
145 
146  wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
147 
148  auto hasElements =
149  [ this ] ( const SELECTION& aSel )
150  {
151  return !m_frame->GetScreen()->Items().empty();
152  };
153 
154  auto sheetTool =
155  [ this ] ( const SELECTION& aSel )
156  {
158  };
159 
160  auto anyTextTool =
161  [ this ] ( const SELECTION& aSel )
162  {
167  };
168 
169  auto duplicateCondition =
170  [] ( const SELECTION& aSel )
171  {
173  return false;
174 
175  return true;
176  };
177 
178  auto orientCondition =
179  [] ( const SELECTION& aSel )
180  {
181  if( aSel.Empty() )
182  return false;
183 
185  return false;
186 
187  SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
188 
189  if( aSel.GetSize() > 1 )
190  return true;
191 
192  switch( item->Type() )
193  {
194  case SCH_MARKER_T:
195  case SCH_JUNCTION_T:
196  case SCH_NO_CONNECT_T:
197  case SCH_PIN_T:
198  return false;
199  case SCH_LINE_T:
200  return item->GetLayer() != LAYER_WIRE && item->GetLayer() != LAYER_BUS;
201  default:
202  return true;
203  }
204  };
205 
206  auto propertiesCondition =
207  []( const SELECTION& aSel )
208  {
209  if( aSel.GetSize() == 0 )
210  return true; // Show drawing-sheet properties
211 
212  SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
213  const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
214 
215  if( !firstItem || !eeSelection )
216  return false;
217 
218  switch( firstItem->Type() )
219  {
220  case SCH_COMPONENT_T:
221  case SCH_SHEET_T:
222  case SCH_SHEET_PIN_T:
223  case SCH_TEXT_T:
224  case SCH_LABEL_T:
225  case SCH_GLOBAL_LABEL_T:
226  case SCH_HIER_LABEL_T:
227  case SCH_FIELD_T:
228  case SCH_BITMAP_T:
229  return aSel.GetSize() == 1;
230 
231  case SCH_LINE_T:
233  return eeSelection->AllItemsHaveLineStroke();
234 
235  case SCH_JUNCTION_T:
236  return eeSelection->AreAllItemsIdentical();
237 
238  default:
239  return false;
240  }
241  };
242 
243  static KICAD_T toLabelTypes[] = { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
244  auto toLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toLabelTypes );
245 
246  static KICAD_T toHLableTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_TEXT_T, EOT };
247  auto toHLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toHLableTypes );
248 
249  static KICAD_T toGLableTypes[] = { SCH_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
250  auto toGLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toGLableTypes );
251 
252  static KICAD_T toTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, EOT };
253  auto toTextlCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toTextTypes );
254 
255  static KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT };
256  auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( entryTypes );
257 
258  static KICAD_T fieldParentTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
259  auto singleFieldParentCondition = E_C::Count( 1 ) && E_C::OnlyTypes( fieldParentTypes );
260 
261  auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
262 
263  //
264  // Add edit actions to the move tool menu
265  //
266  if( moveTool )
267  {
268  CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
269 
270  moveMenu.AddSeparator();
271  moveMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition );
272  moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition );
273  moveMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition );
274  moveMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition );
275 
276  moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
281 
282  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
283  symUnitMenu->SetTool( this );
284  m_menu.AddSubMenu( symUnitMenu );
285  moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
286 
287  moveMenu.AddSeparator();
291  moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
292 
293  moveMenu.AddSeparator();
294  moveMenu.AddItem( ACTIONS::selectAll, hasElements );
295  }
296 
297  //
298  // Add editing actions to the drawing tool menu
299  //
300  CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
301 
302  drawMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
303  drawMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
304  drawMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
305  drawMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
306 
307  drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
311  drawMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 );
313 
314  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
315  symUnitMenu2->SetTool( drawingTools );
316  drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 );
317  drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
318 
320 
321  drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
322  drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
323  drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
324  drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
325  drawMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetTool && E_C::Idle, 250 );
326 
327  //
328  // Add editing actions to the selection tool menu
329  //
331 
332  selToolMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
333  selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
334  selToolMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
335  selToolMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
336 
337  selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
339  selToolMenu.AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
341  selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 );
343 
344  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
345  symUnitMenu3->SetTool( m_selectionTool );
346  m_selectionTool->GetToolMenu().AddSubMenu( symUnitMenu3 );
347  selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
348 
352 
353  selToolMenu.AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
354  selToolMenu.AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
355  selToolMenu.AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
356  selToolMenu.AddItem( EE_ACTIONS::toText, toTextlCondition, 200 );
357  selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, singleSheetCondition, 250 );
358 
359  selToolMenu.AddSeparator( 300 );
360  selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
361  selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
362  selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
363  selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
364  selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
365  selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
366 
367  selToolMenu.AddSeparator( 400 );
368  selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
369 
370 
371  return true;
372 }
373 
374 
376  SCH_TEXT_T,
377  SCH_LABEL_T,
380  SCH_FIELD_T,
383  SCH_SHEET_T,
384  SCH_BITMAP_T,
387  SCH_LINE_T,
390  EOT
391 };
392 
393 
394 int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
395 {
396  bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
398 
399  if( selection.GetSize() == 0 )
400  return 0;
401 
402  SCH_ITEM* head = nullptr;
403  int principalItemCount = 0; // User-selected items (as opposed to connected wires)
404  wxPoint rotPoint;
405  bool moving = false;
406  bool connections = false;
407 
408  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
409  {
410  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
411 
412  if( item->HasFlag( TEMP_SELECTED ) )
413  continue;
414 
415  principalItemCount++;
416 
417  if( !head )
418  head = item;
419  }
420 
421  if( head && head->IsMoving() )
422  moving = true;
423 
424  if( principalItemCount == 1 )
425  {
426  rotPoint = head->GetPosition();
427 
428  if( !moving )
430 
431  switch( head->Type() )
432  {
433  case SCH_COMPONENT_T:
434  {
435  SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( head );
436 
437  if( clockwise )
438  component->SetOrientation( CMP_ROTATE_CLOCKWISE );
439  else
441 
443  component->AutoAutoplaceFields( m_frame->GetScreen() );
444 
445  break;
446  }
447 
448  case SCH_TEXT_T:
449  case SCH_LABEL_T:
450  case SCH_GLOBAL_LABEL_T:
451  case SCH_HIER_LABEL_T:
452  {
453  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
454  textItem->Rotate90( clockwise );
455  break;
456  }
457 
458  case SCH_SHEET_PIN_T:
459  {
460  // Rotate pin within parent sheet
461  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
462  SCH_SHEET* sheet = pin->GetParent();
463 
464  for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
465  pin->Rotate( sheet->GetBoundingBox().GetCenter() );
466 
467  break;
468  }
469 
470  case SCH_LINE_T:
471  case SCH_BUS_BUS_ENTRY_T:
473  for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
474  head->Rotate( rotPoint );
475 
476  break;
477 
478  case SCH_FIELD_T:
479  {
480  SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
481 
482  if( field->GetTextAngle() == TEXT_ANGLE_HORIZ )
483  field->SetTextAngle( TEXT_ANGLE_VERT );
484  else
485  field->SetTextAngle( TEXT_ANGLE_HORIZ );
486 
487  // Now that we're moving a field, they're no longer autoplaced.
488  static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
489 
490  break;
491  }
492 
493  case SCH_BITMAP_T:
494  for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
495  head->Rotate( rotPoint );
496 
497  // The bitmap is cached in Opengl: clear the cache to redraw
499  break;
500 
501  case SCH_SHEET_T:
502  {
503  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
504  rotPoint = m_frame->GetNearestGridPosition( sheet->GetRotationCenter() );
505 
506  // Rotate the sheet on itself. Sheets do not have an anchor point.
507  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
508  sheet->Rotate( rotPoint );
509 
510  break;
511  }
512 
513  default:
514  break;
515  }
516 
517  connections = head->IsConnectable();
518  m_frame->UpdateItem( head );
519  }
520  else
521  {
522  rotPoint = m_frame->GetNearestGridPosition( (wxPoint)selection.GetCenter() );
523  }
524 
525  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
526  {
527  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
528 
529  // We've already rotated the user selected item if there was only one. We're just
530  // here to rotate the ends of wires that were attached to it.
531  if( principalItemCount == 1 && !item->HasFlag( TEMP_SELECTED ) )
532  continue;
533 
534  if( !moving )
535  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
536 
537  for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
538  {
539  if( item->Type() == SCH_LINE_T )
540  {
541  SCH_LINE* line = (SCH_LINE*) item;
542 
543  if( item->HasFlag( STARTPOINT ) )
544  line->RotateStart( rotPoint );
545 
546  if( item->HasFlag( ENDPOINT ) )
547  line->RotateEnd( rotPoint );
548  }
549  else if( item->Type() == SCH_SHEET_PIN_T )
550  {
551  if( item->GetParent()->IsSelected() )
552  {
553  // parent will rotate us
554  }
555  else
556  {
557  // rotate within parent
558  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
559  SCH_SHEET* sheet = pin->GetParent();
560 
561  pin->Rotate( sheet->GetBoundingBox().GetCenter() );
562  }
563  }
564  else if( item->Type() == SCH_FIELD_T )
565  {
566  if( item->GetParent()->IsSelected() )
567  {
568  // parent will rotate us
569  }
570  else
571  {
572  item->Rotate( rotPoint );
573  }
574  }
575  else
576  {
577  item->Rotate( rotPoint );
578  }
579  }
580 
581  connections |= item->IsConnectable();
582  m_frame->UpdateItem( item );
583  }
584 
586 
587  if( moving )
588  {
590  }
591  else
592  {
593  if( selection.IsHover() )
595 
596  if( connections )
598 
599  m_frame->OnModify();
600  }
601 
602  return 0;
603 }
604 
605 
606 int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
607 {
609 
610  if( selection.GetSize() == 0 )
611  return 0;
612 
613  wxPoint mirrorPoint;
614  bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
615  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
616  bool connections = false;
617  bool moving = item->IsMoving();
618 
619  if( selection.GetSize() == 1 )
620  {
621  if( !moving )
623 
624  switch( item->Type() )
625  {
626  case SCH_COMPONENT_T:
627  {
628  SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
629 
630  if( vertical )
631  component->SetOrientation( CMP_MIRROR_X );
632  else
633  component->SetOrientation( CMP_MIRROR_Y );
634 
636  component->AutoAutoplaceFields( m_frame->GetScreen() );
637 
638  break;
639  }
640 
641  case SCH_TEXT_T:
642  case SCH_LABEL_T:
643  case SCH_GLOBAL_LABEL_T:
644  case SCH_HIER_LABEL_T:
645  {
646  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
647  textItem->MirrorSpinStyle( !vertical );
648  break;
649  }
650 
651  case SCH_SHEET_PIN_T:
652  {
653  // mirror within parent sheet
654  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
655  SCH_SHEET* sheet = pin->GetParent();
656 
657  if( vertical )
658  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
659  else
660  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
661 
662  break;
663  }
664 
665  case SCH_BUS_BUS_ENTRY_T:
667  if( vertical )
668  item->MirrorVertically( item->GetPosition().y );
669  else
670  item->MirrorHorizontally( item->GetPosition().x );
671  break;
672 
673  case SCH_FIELD_T:
674  {
675  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
676 
677  if( vertical )
679  else
681 
682  // Now that we're re-justifying a field, they're no longer autoplaced.
683  static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
684 
685  break;
686  }
687 
688  case SCH_BITMAP_T:
689  if( vertical )
690  item->MirrorVertically( item->GetPosition().y );
691  else
692  item->MirrorHorizontally( item->GetPosition().x );
693 
694  // The bitmap is cached in Opengl: clear the cache to redraw
696  break;
697 
698  case SCH_SHEET_T:
699  // Mirror the sheet on itself. Sheets do not have a anchor point.
700  mirrorPoint = m_frame->GetNearestHalfGridPosition( item->GetBoundingBox().Centre() );
701 
702  if( vertical )
703  item->MirrorVertically( mirrorPoint.y );
704  else
705  item->MirrorHorizontally( mirrorPoint.x );
706 
707  break;
708 
709  default:
710  break;
711  }
712 
713  connections = item->IsConnectable();
714  m_frame->UpdateItem( item );
715  }
716  else if( selection.GetSize() > 1 )
717  {
718  mirrorPoint = m_frame->GetNearestHalfGridPosition( (wxPoint)selection.GetCenter() );
719 
720  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
721  {
722  item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
723 
724  if( !moving )
725  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
726 
727  if( item->Type() == SCH_SHEET_PIN_T )
728  {
729  if( item->GetParent()->IsSelected() )
730  {
731  // parent will mirror us
732  }
733  else
734  {
735  // mirror within parent sheet
736  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
737  SCH_SHEET* sheet = pin->GetParent();
738 
739  if( vertical )
740  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
741  else
742  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
743  }
744  }
745  else
746  {
747  if( vertical )
748  item->MirrorVertically( mirrorPoint.y );
749  else
750  item->MirrorHorizontally( mirrorPoint.x );
751  }
752 
753  connections |= item->IsConnectable();
754  m_frame->UpdateItem( item );
755  }
756  }
757 
759 
760  // Update R-Tree for modified items
761  for( EDA_ITEM* selected : selection )
762  updateItem( selected, true );
763 
764  if( item->IsMoving() )
765  {
767  }
768  else
769  {
770  if( selection.IsHover() )
772 
773  if( connections )
775 
776  m_frame->OnModify();
777  }
778 
779  return 0;
780 }
781 
782 
784 {
786  SCH_LINE_T,
789  SCH_TEXT_T,
790  SCH_LABEL_T,
794  SCH_SHEET_T,
796  EOT
797 };
798 
799 
801 {
803 
804  if( selection.GetSize() == 0 )
805  return 0;
806 
807  // Doing a duplicate of a new object doesn't really make any sense; we'd just end
808  // up dragging around a stack of objects...
809  if( selection.Front()->IsNew() )
810  return 0;
811 
812  EDA_ITEMS newItems;
813 
814  // Keep track of existing sheet paths. Duplicating a selection can modify this list
815  bool copiedSheets = false;
816  SCH_SHEET_LIST initial_sheetpathList = m_frame->Schematic().GetSheets();
817 
818  for( unsigned ii = 0; ii < selection.GetSize(); ++ii )
819  {
820  SCH_ITEM* oldItem = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
821  SCH_ITEM* newItem = oldItem->Duplicate();
822  newItem->SetFlags( IS_NEW );
823  newItems.push_back( newItem );
824  saveCopyInUndoList( newItem, UNDO_REDO::NEWITEM, ii > 0 );
825 
826  switch( newItem->Type() )
827  {
828  case SCH_JUNCTION_T:
829  case SCH_LINE_T:
830  case SCH_BUS_BUS_ENTRY_T:
832  case SCH_TEXT_T:
833  case SCH_LABEL_T:
834  case SCH_GLOBAL_LABEL_T:
835  case SCH_HIER_LABEL_T:
836  case SCH_NO_CONNECT_T:
837  newItem->SetParent( m_frame->GetScreen() );
838  m_frame->AddToScreen( newItem, m_frame->GetScreen() );
839  break;
840 
841  case SCH_SHEET_T:
842  {
843  SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets();
844  SCH_SHEET* sheet = (SCH_SHEET*) newItem;
845  SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME];
846  wxString baseName = nameField.GetText();
847  wxString number;
848 
849  while( !baseName.IsEmpty() && wxIsdigit( baseName.Last() ) )
850  {
851  number = baseName.Last() + number;
852  baseName.RemoveLast();
853  }
854 
855  int uniquifier = std::max( 0, wxAtoi( number ) ) + 1;
856  wxString candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
857 
858  while( hierarchy.NameExists( candidateName ) )
859  candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
860 
861  nameField.SetText( candidateName );
862 
863  sheet->SetParent( m_frame->GetCurrentSheet().Last() );
864  m_frame->AddToScreen( sheet, m_frame->GetScreen() );
865 
866  copiedSheets = true;
867  break;
868  }
869 
870  case SCH_COMPONENT_T:
871  {
872  SCH_COMPONENT* component = (SCH_COMPONENT*) newItem;
873  component->ClearAnnotation( NULL );
874  component->SetParent( m_frame->GetScreen() );
875  m_frame->AddToScreen( component, m_frame->GetScreen() );
876  break;
877  }
878 
879  default:
880  break;
881  }
882  }
883 
884  if( copiedSheets )
885  {
886  // We clear annotation of new sheet paths.
887  // Annotation of new components added in current sheet is already cleared.
888  SCH_SCREENS screensList( &m_frame->Schematic().Root() );
889  screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
891  }
892 
894  m_toolMgr->RunAction( EE_ACTIONS::addItemsToSel, true, &newItems );
896 
897  return 0;
898 }
899 
900 
902 {
903  SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
904 
905  if( !sourceItem )
906  return 0;
907 
909 
910  SCH_ITEM* newItem = sourceItem->Duplicate();
911  bool performDrag = false;
912 
913  // If cloning a component then put into 'move' mode.
914  if( newItem->Type() == SCH_COMPONENT_T )
915  {
916  wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( true );
917  newItem->Move( cursorPos - newItem->GetPosition() );
918  performDrag = true;
919  }
920  else
921  {
922  if( m_isSymbolEditor )
923  {
924  auto* cfg = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
925 
926  if( dynamic_cast<SCH_TEXT*>( newItem ) )
927  {
928  SCH_TEXT* text = static_cast<SCH_TEXT*>( newItem );
929  text->IncrementLabel( cfg->m_Repeat.label_delta );
930  }
931 
932  newItem->Move( wxPoint( Mils2iu( cfg->m_Repeat.x_step ),
933  Mils2iu( cfg->m_Repeat.y_step ) ) );
934  }
935  else
936  {
937  EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
938 
939  if( dynamic_cast<SCH_TEXT*>( newItem ) )
940  {
941  SCH_TEXT* text = static_cast<SCH_TEXT*>( newItem );
942 
943  // If incrementing tries to go below zero, tell user why the value is repeated
944 
945  if( !text->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
946  m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
947  }
948 
949  newItem->Move( wxPoint( Mils2iu( cfg->m_Drawing.default_repeat_offset_x ),
950  Mils2iu( cfg->m_Drawing.default_repeat_offset_y ) ) );
951  }
952 
953  }
954 
955  newItem->SetFlags( IS_NEW );
956  m_frame->AddToScreen( newItem, m_frame->GetScreen() );
958 
959  m_selectionTool->AddItemToSel( newItem );
960 
961  // Components need to be handled by the move tool. The move tool will handle schematic
962  // cleanup routines
963  if( performDrag )
965 
966  newItem->ClearFlags();
967 
968  if( !performDrag && newItem->IsConnectable() )
969  {
971  new_sel.Add( newItem );
972 
976  }
977 
978  // newItem newItem, now that it has been moved, thus saving new position.
979  m_frame->SaveCopyForRepeatItem( newItem );
980 
981  return 0;
982 }
983 
984 
986 {
987  SCH_MARKER_T,
989  SCH_LINE_T,
992  SCH_TEXT_T,
993  SCH_LABEL_T,
997  SCH_SHEET_T,
1000  SCH_BITMAP_T,
1001  EOT
1002 };
1003 
1004 
1006 {
1007  SCH_SCREEN* screen = m_frame->GetScreen();
1009  bool appendToUndo = false;
1010  std::vector<wxPoint> pts;
1011 
1012  if( items.empty() )
1013  return 0;
1014 
1015  // Don't leave a freed pointer in the selection
1017 
1018  for( EDA_ITEM* item : items )
1019  item->ClearFlags( STRUCT_DELETED );
1020 
1021  for( EDA_ITEM* item : items )
1022  {
1023  SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1024 
1025  if( !sch_item )
1026  continue;
1027 
1028  if( sch_item->IsConnectable() )
1029  {
1030  std::vector<wxPoint> tmp_pts = sch_item->GetConnectionPoints();
1031  pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1032  }
1033 
1034  if( sch_item->Type() == SCH_JUNCTION_T )
1035  {
1036  sch_item->SetFlags( STRUCT_DELETED );
1037  // clean up junctions at the end
1038  }
1039  else if( sch_item->Type() == SCH_SHEET_PIN_T )
1040  {
1041  SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1042  SCH_SHEET* sheet = pin->GetParent();
1043 
1044  if( !alg::contains( items, sheet ) )
1045  {
1046  pin->SetFlags( STRUCT_DELETED );
1047  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1048  appendToUndo = true;
1049 
1050  updateItem( pin, false );
1051 
1052  sheet->RemovePin( pin );
1053  }
1054  }
1055  else
1056  {
1057  sch_item->SetFlags( STRUCT_DELETED );
1058  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1059  appendToUndo = true;
1060 
1061  updateItem( sch_item, false );
1062 
1063  m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
1064 
1065  if( sch_item->Type() == SCH_SHEET_T )
1067  }
1068  }
1069 
1070  for( auto point : pts )
1071  {
1072  SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1073 
1074  if( !junction )
1075  continue;
1076 
1077  if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsJunctionNeeded( point ) )
1078  m_frame->DeleteJunction( junction, appendToUndo );
1079  }
1080 
1082 
1083  m_frame->GetCanvas()->Refresh();
1084  m_frame->OnModify();
1085 
1086  return 0;
1087 }
1088 
1089 
1090 #define HITTEST_THRESHOLD_PIXELS 5
1091 
1092 
1094 {
1095  std::string tool = aEvent.GetCommandStr().get();
1096  PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
1097 
1099  m_pickerItem = nullptr;
1100 
1101  // Deactivate other tools; particularly important if another PICKER is currently running
1102  Activate();
1103 
1104  picker->SetCursor( KICURSOR::REMOVE );
1105  picker->SetSnapping( false );
1106 
1107  picker->SetClickHandler(
1108  [this]( const VECTOR2D& aPosition ) -> bool
1109  {
1110  if( m_pickerItem )
1111  {
1112  SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( m_pickerItem );
1113 
1114  if( sch_item && sch_item->IsLocked() )
1115  {
1116  STATUS_TEXT_POPUP statusPopup( m_frame );
1117  statusPopup.SetText( _( "Item locked." ) );
1118  statusPopup.PopupFor( 2000 );
1119  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
1120  return true;
1121  }
1122 
1124  selectionTool->UnbrightenItem( m_pickerItem );
1125  selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1127  m_pickerItem = nullptr;
1128  }
1129 
1130  return true;
1131  } );
1132 
1133  picker->SetMotionHandler(
1134  [this]( const VECTOR2D& aPos )
1135  {
1136  EE_COLLECTOR collector;
1137  collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1138  collector.Collect( m_frame->GetScreen(), deletableItems, (wxPoint) aPos );
1139 
1141  selectionTool->GuessSelectionCandidates( collector, aPos );
1142 
1143  EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1144 
1145  if( m_pickerItem != item )
1146  {
1147  if( m_pickerItem )
1148  selectionTool->UnbrightenItem( m_pickerItem );
1149 
1150  m_pickerItem = item;
1151 
1152  if( m_pickerItem )
1153  selectionTool->BrightenItem( m_pickerItem );
1154  }
1155  } );
1156 
1157  picker->SetFinalizeHandler(
1158  [this]( const int& aFinalState )
1159  {
1160  if( m_pickerItem )
1162 
1163  // Wake the selection tool after exiting to ensure the cursor gets updated
1165  } );
1166 
1167  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1168 
1169  return 0;
1170 }
1171 
1172 
1174 {
1175  // Save old component in undo list if not already in edit, or moving.
1176  if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1178 
1179  wxString title = wxString::Format( _( "Edit %s Field" ), aField->GetName() );
1180 
1181  DIALOG_SCH_EDIT_ONE_FIELD dlg( m_frame, title, aField );
1182 
1183  // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1184  if( dlg.ShowQuasiModal() != wxID_OK )
1185  return;
1186 
1187  dlg.UpdateField( aField, &m_frame->GetCurrentSheet() );
1188 
1189  if( m_frame->eeconfig()->m_AutoplaceFields.enable || aField->GetParent()->Type() == SCH_SHEET_T )
1190  static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1191 
1192  m_frame->UpdateItem( aField );
1193  m_frame->OnModify();
1194 
1195  // This must go after OnModify() so that the connectivity graph will have been updated.
1197 }
1198 
1199 
1201 {
1202  static KICAD_T Nothing[] = { EOT };
1203  static KICAD_T CmpOrReference[] = { SCH_FIELD_LOCATE_REFERENCE_T, SCH_COMPONENT_T, EOT };
1204  static KICAD_T CmpOrValue[] = { SCH_FIELD_LOCATE_VALUE_T, SCH_COMPONENT_T, EOT };
1205  static KICAD_T CmpOrFootprint[] = { SCH_FIELD_LOCATE_FOOTPRINT_T, SCH_COMPONENT_T, EOT };
1206 
1207  KICAD_T* filter = Nothing;
1208 
1209  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1210  filter = CmpOrReference;
1211  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1212  filter = CmpOrValue;
1213  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1214  filter = CmpOrFootprint;
1215 
1216  EE_SELECTION& selection = m_selectionTool->RequestSelection( filter );
1217 
1218  if( selection.Size() != 1 )
1219  return 0;
1220 
1221  SCH_ITEM* item = (SCH_ITEM*) selection.Front();
1222 
1223  if( item->Type() == SCH_COMPONENT_T )
1224  {
1225  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
1226 
1227  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1228  editFieldText( component->GetField( REFERENCE_FIELD ) );
1229  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1230  editFieldText( component->GetField( VALUE_FIELD ) );
1231  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1232  editFieldText( component->GetField( FOOTPRINT_FIELD ) );
1233  }
1234  else if( item->Type() == SCH_FIELD_T )
1235  {
1236  editFieldText( (SCH_FIELD*) item );
1237  }
1238 
1239  if( selection.IsHover() )
1241 
1242  return 0;
1243 }
1244 
1245 
1247 {
1249 
1250  if( selection.Empty() )
1251  return 0;
1252 
1253  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
1254 
1255  if( !item->IsNew() )
1257 
1258  item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1259 
1260  updateItem( item, true );
1261  m_frame->OnModify();
1262 
1263  if( selection.IsHover() )
1265 
1266  return 0;
1267 }
1268 
1269 
1271 {
1272  SCH_COMPONENT* selectedSymbol = nullptr;
1274 
1275  if( !selection.Empty() )
1276  selectedSymbol = dynamic_cast<SCH_COMPONENT*>( selection.Front() );
1277 
1279 
1280  if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1281  || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1282  {
1284  }
1285 
1286  DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1287 
1288  dlg.ShowQuasiModal();
1289 
1290  return 0;
1291 }
1292 
1293 
1295 {
1297 
1298  if( selection.Empty() )
1299  return 0;
1300 
1301  SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front();
1302 
1304  && component->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1305  {
1306  return 0;
1307  }
1308 
1310  && component->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
1311  {
1312  return 0;
1313  }
1314 
1315  if( !component->IsNew() )
1316  saveCopyInUndoList( component, UNDO_REDO::CHANGED );
1317 
1318  m_frame->ConvertPart( component );
1319 
1320  if( component->IsNew() )
1322 
1323  if( selection.IsHover() )
1325 
1326  return 0;
1327 }
1328 
1329 
1331 {
1333 
1334  if( selection.Empty() )
1335  {
1337  {
1339  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1340 
1341  if( ds && ds->HitTestDrawingSheetItems( getView(), (wxPoint) cursorPos ) )
1343  }
1344 
1345  return 0;
1346  }
1347 
1348  SCH_ITEM* item = (SCH_ITEM*) selection.Front();
1349 
1350  switch( item->Type() )
1351  {
1352  case SCH_LINE_T:
1353  case SCH_BUS_WIRE_ENTRY_T:
1354  if( !selection.AllItemsHaveLineStroke() )
1355  return 0;
1356 
1357  break;
1358 
1359  case SCH_JUNCTION_T:
1360  if( !selection.AreAllItemsIdentical() )
1361  return 0;
1362 
1363  break;
1364 
1365  default:
1366  if( selection.Size() > 1 )
1367  return 0;
1368 
1369  break;
1370  }
1371 
1372  switch( item->Type() )
1373  {
1374  case SCH_COMPONENT_T:
1375  {
1376  SCH_COMPONENT* component = (SCH_COMPONENT*) item;
1377  DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, component );
1378 
1379  // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1380  // frame. Therefore this dialog as a modal frame parent, MUST be run under
1381  // quasimodal mode for the quasimodal frame support to work. So don't use
1382  // the QUASIMODAL macros here.
1383  int retval = symbolPropsDialog.ShowQuasiModal();
1384 
1385  if( retval == SYMBOL_PROPS_EDIT_OK )
1386  {
1388  component->AutoAutoplaceFields( m_frame->GetScreen() );
1389 
1391  m_frame->OnModify();
1392  }
1393  else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1394  {
1395  auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true );
1396 
1397  editor->LoadSymbolFromSchematic( component );
1398 
1399  editor->Show( true );
1400  editor->Raise();
1401  }
1402  else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1403  {
1404  auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true );
1405 
1406  editor->LoadSymbolAndSelectLib( component->GetLibId(), component->GetUnit(),
1407  component->GetConvert() );
1408 
1409  editor->Show( true );
1410  editor->Raise();
1411  }
1412  else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1413  {
1415  dlg.ShowQuasiModal();
1416  }
1417  else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1418  {
1420  dlg.ShowQuasiModal();
1421  }
1422  }
1423  break;
1424 
1425  case SCH_SHEET_T:
1426  {
1427  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1428  bool doClearAnnotation;
1429  bool doRefresh = false;
1430 
1431  // Keep track of existing sheet paths. EditSheet() can modify this list.
1432  // Note that we use the validity checking/repairing version here just to make sure
1433  // we've got a valid hierarchy to begin with.
1434  SCH_SHEET_LIST initial_sheetpathList( &m_frame->Schematic().Root(), true );
1435 
1436  doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1437  &doClearAnnotation );
1438 
1439  // If the sheet file is changed and new sheet contents are loaded then we have to
1440  // clear the annotations on the new content (as it may have been set from some other
1441  // sheet path reference)
1442  if( doClearAnnotation )
1443  {
1444  SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1445  // We clear annotation of new sheet paths here:
1446  screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
1447  // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1448  // path, but components managed by its sheet path must have their annotation
1449  // cleared, because they are new:
1451  }
1452 
1453  if( doRefresh )
1454  {
1456  m_frame->GetCanvas()->Refresh();
1458  }
1459 
1460  break;
1461  }
1462 
1463  case SCH_SHEET_PIN_T:
1464  {
1465  SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) item;
1467 
1468  // QuasiModal required for help dialog
1469  if( dlg.ShowQuasiModal() == wxID_OK )
1470  {
1472  m_frame->OnModify();
1473  }
1474  }
1475  break;
1476 
1477  case SCH_TEXT_T:
1478  case SCH_LABEL_T:
1479  case SCH_GLOBAL_LABEL_T:
1480  case SCH_HIER_LABEL_T:
1481  {
1482  DIALOG_LABEL_EDITOR dlg( m_frame, (SCH_TEXT*) item );
1483 
1484  // Must be quasi modal for syntax help
1485  if( dlg.ShowQuasiModal() == wxID_OK )
1486  {
1488  m_frame->OnModify();
1489  }
1490  }
1491  break;
1492 
1493  case SCH_FIELD_T:
1494  editFieldText( (SCH_FIELD*) item );
1495  break;
1496 
1497  case SCH_BITMAP_T:
1498  {
1499  SCH_BITMAP* bitmap = (SCH_BITMAP*) item;
1500  DIALOG_IMAGE_EDITOR dlg( m_frame, bitmap->GetImage() );
1501 
1502  if( dlg.ShowModal() == wxID_OK )
1503  {
1504  // save old image in undo list if not already in edit
1505  if( bitmap->GetEditFlags() == 0 )
1507 
1508  dlg.TransferToImage( bitmap->GetImage() );
1509 
1510  // The bitmap is cached in Opengl: clear the cache in case it has become invalid
1511  getView()->RecacheAllItems();
1513  m_frame->OnModify();
1514  }
1515  }
1516  break;
1517 
1518  case SCH_LINE_T:
1519  case SCH_BUS_WIRE_ENTRY_T:
1520  {
1521  std::deque<SCH_ITEM*> strokeItems;
1522 
1523  for( auto selItem : selection.Items() )
1524  {
1525  SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( selItem );
1526 
1527  if( schItem && schItem->HasLineStroke() )
1528  strokeItems.push_back( schItem );
1529  else
1530  return 0;
1531  }
1532 
1533  DIALOG_EDIT_LINE_STYLE dlg( m_frame, strokeItems );
1534 
1535  if( dlg.ShowModal() == wxID_OK )
1536  {
1538  m_frame->OnModify();
1539  }
1540  }
1541  break;
1542 
1543  case SCH_JUNCTION_T:
1544  {
1545  std::deque<SCH_JUNCTION*> junctions;
1546 
1547  for( auto selItem : selection.Items() )
1548  {
1549  SCH_JUNCTION* junction = dynamic_cast<SCH_JUNCTION*>( selItem );
1550 
1551  wxCHECK( junction, 0 );
1552 
1553  junctions.push_back( junction );
1554  }
1555 
1556  DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1557 
1558  if( dlg.ShowModal() == wxID_OK )
1559  {
1561  m_frame->OnModify();
1562  }
1563  }
1564  break;
1565 
1566  case SCH_MARKER_T: // These items have no properties to edit
1567  case SCH_NO_CONNECT_T:
1568  break;
1569 
1570  default: // Unexpected item
1571  wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + item->GetClass() );
1572  }
1573 
1574  updateItem( item, true );
1575 
1576  if( selection.IsHover() )
1578 
1579  return 0;
1580 }
1581 
1582 
1584 {
1585  KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
1587  EE_SELECTION& selection = m_selectionTool->RequestSelection( allTextTypes );
1588 
1589  for( unsigned int i = 0; i < selection.GetSize(); ++i )
1590  {
1591  SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( selection.GetItem( i ) );
1592 
1593  if( text && text->Type() != convertTo )
1594  {
1595  bool selected = text->IsSelected();
1596  SCH_TEXT* newtext = nullptr;
1597  const wxPoint& position = text->GetPosition();
1598  LABEL_SPIN_STYLE orientation = text->GetLabelSpinStyle();
1599  wxString txt = UnescapeString( text->GetText() );
1600 
1601  // There can be characters in a SCH_TEXT object that can break labels so we have to
1602  // fix them here.
1603  if( text->Type() == SCH_TEXT_T )
1604  {
1605  txt.Replace( "\n", "_" );
1606  txt.Replace( "\r", "_" );
1607  txt.Replace( "\t", "_" );
1608  txt.Replace( " ", "_" );
1609  }
1610 
1611  // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
1612  if( convertTo != SCH_TEXT_T )
1613  txt = EscapeString( txt, CTX_NETNAME );
1614 
1615  switch( convertTo )
1616  {
1617  case SCH_LABEL_T: newtext = new SCH_LABEL( position, txt ); break;
1618  case SCH_GLOBAL_LABEL_T: newtext = new SCH_GLOBALLABEL( position, txt ); break;
1619  case SCH_HIER_LABEL_T: newtext = new SCH_HIERLABEL( position, txt ); break;
1620  case SCH_TEXT_T: newtext = new SCH_TEXT( position, txt ); break;
1621 
1622  default:
1623  wxFAIL_MSG( wxString::Format( "Invalid text type: %d.", convertTo ) );
1624  return 0;
1625  }
1626 
1627  // Copy the old text item settings to the new one. Justifications are not copied
1628  // because they are not used in labels. Justifications will be set to default value
1629  // in the new text item type.
1630  //
1631  newtext->SetFlags( text->GetEditFlags() );
1632  newtext->SetShape( text->GetShape() );
1633  newtext->SetLabelSpinStyle( orientation );
1634  newtext->SetTextSize( text->GetTextSize() );
1635  newtext->SetTextThickness( text->GetTextThickness() );
1636  newtext->SetItalic( text->IsItalic() );
1637  newtext->SetBold( text->IsBold() );
1638  newtext->SetIsDangling( text->IsDangling() );
1639 
1640  if( selected )
1642 
1643  if( !text->IsNew() )
1644  {
1646  saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
1647 
1649  m_frame->AddToScreen( newtext, m_frame->GetScreen() );
1650 
1651  if( convertTo == SCH_GLOBAL_LABEL_T )
1652  static_cast<SCH_GLOBALLABEL*>( newtext )->UpdateIntersheetRefProps();
1653  }
1654 
1655  if( selected )
1656  m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
1657 
1658  // Otherwise, pointer is owned by the undo stack
1659  if( text->IsNew() )
1660  delete text;
1661 
1662  if( convertTo == SCH_TEXT_T )
1663  {
1664  if( newtext->IsDangling() )
1665  {
1666  newtext->SetIsDangling( false );
1667  getView()->Update( newtext, KIGFX::REPAINT );
1668  }
1669  }
1670  else
1672 
1673  m_frame->OnModify();
1674  }
1675  }
1676 
1677  if( selection.IsHover() )
1679 
1680  return 0;
1681 }
1682 
1683 
1685 {
1686  wxPoint cursorPos = wxPoint( getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ) );
1688 
1689  std::vector<SCH_LINE*> lines;
1690 
1691  for( auto& item : selection )
1692  {
1693  if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
1694  {
1695  if( !line->IsEndPoint( cursorPos ) )
1696  lines.push_back( line );
1697  }
1698  }
1699 
1701  m_frame->StartNewUndo();
1702 
1703  for( SCH_LINE* line : lines )
1704  m_frame->BreakSegment( line, cursorPos );
1705 
1706  if( !lines.empty() )
1707  {
1708  if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) )
1709  m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false );
1710 
1712 
1713  m_frame->OnModify();
1714  m_frame->GetCanvas()->Refresh();
1715 
1717  }
1718 
1719  return 0;
1720 }
1721 
1722 
1724 {
1726  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1727 
1728  if( !sheet )
1729  return 0;
1730 
1731  if( !sheet->HasUndefinedPins() )
1732  {
1733  DisplayInfoMessage( m_frame, _( "There are no unreferenced pins in this sheet to remove." ) );
1734  return 0;
1735  }
1736 
1737  if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
1738  return 0;
1739 
1741 
1742  sheet->CleanupSheet();
1743 
1744  updateItem( sheet, true );
1745  m_frame->OnModify();
1746 
1747  if( selection.IsHover() )
1749 
1750  return 0;
1751 }
1752 
1753 
1755 {
1757 
1758  if( selection.GetSize() > 1 )
1759  return 0;
1760 
1761  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1762 
1763  SCH_SHEET_PATH instance = m_frame->GetCurrentSheet();
1764 
1765  SCH_SCREEN* screen;
1766 
1767  if( sheet )
1768  {
1769  // When changing the page number of a selected sheet, the current screen owns the sheet.
1770  screen = m_frame->GetScreen();
1771 
1772  instance.push_back( sheet );
1773  }
1774  else
1775  {
1776  SCH_SHEET_PATH prevInstance = instance;
1777 
1778  // When change the page number in the screen, the previous screen owns the sheet.
1779  if( prevInstance.size() )
1780  {
1781  prevInstance.pop_back();
1782  screen = prevInstance.LastScreen();
1783  }
1784  else
1785  {
1786  // The root sheet and root screen are effectively the same thing.
1787  screen = m_frame->GetScreen();
1788  }
1789 
1790  sheet = m_frame->GetCurrentSheet().Last();
1791  }
1792 
1793  wxString msg;
1794  wxString sheetPath = instance.PathHumanReadable( false );
1795  wxString pageNumber = instance.GetPageNumber();
1796 
1797  msg.Printf( _( "Enter page number for sheet path%s" ),
1798  ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
1799 
1800  wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
1801 
1802  dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
1803 
1804  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
1805  return 0;
1806 
1807  m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
1808 
1809  instance.SetPageNumber( dlg.GetValue() );
1810 
1811  if( instance == m_frame->GetCurrentSheet() )
1812  {
1813  m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
1815  }
1816 
1817  m_frame->OnModify();
1818 
1819  return 0;
1820 }
1821 
1822 
1824 {
1829  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorV.MakeEvent() );
1830  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorH.MakeEvent() );
1831  Go( &SCH_EDIT_TOOL::DoDelete, ACTIONS::doDelete.MakeEvent() );
1833 
1850 
1853 
1857 }
Field Reference of part, i.e. "IC21".
static TOOL_ACTION editPageNumber
Definition: ee_actions.h:152
const BITMAP_OPAQUE component_select_unit_xpm[1]
bool IsDangling() const override
Definition: sch_text.h:303
bool empty() const
Definition: sch_rtree.h:166
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:50
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.
bool IsBold() const
Definition: eda_text.h:190
static TOOL_ACTION properties
Definition: ee_actions.h:118
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:51
bool SchematicCleanUp(SCH_SCREEN *aScreen=nullptr)
Performs routine schematic cleaning including breaking wire and buses and deleting identical objects ...
bool IsCurrentTool(const TOOL_ACTION &aAction) const
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:237
#define HITTEST_THRESHOLD_PIXELS
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
int m_Threshold
Definition: collector.h:248
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
virtual bool IsConnectable() const
Definition: sch_item.h:376
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:56
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:61
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsHover() const
Definition: selection.h:72
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
Definition: sch_sheet.h:169
void SetPageNumber(const wxString &aPageNumber)
Definition: base_screen.h:83
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:208
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:123
virtual std::vector< wxPoint > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:390
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Returns a mandatory field in this symbol.
Definition: sch_symbol.cpp:688
static TOOL_ACTION breakBus
Definition: ee_actions.h:132
static TOOL_ACTION pageSettings
Definition: actions.h:59
static SELECTION_CONDITION SingleSymbol
static KICAD_T duplicatableItems[]
bool IsSelected() const
Definition: eda_item.h:172
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:45
This file is part of the common library.
static TOOL_ACTION doDelete
Definition: actions.h:75
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:373
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.).
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)
Function Collect scans a EDA_ITEM using this class's Inspector method, which does the collection.
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: ee_actions.h:61
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:460
bool BreakSegment(SCH_LINE *aSegment, const wxPoint &aPoint, SCH_LINE **aNewSegment=NULL, SCH_SCREEN *aScreen=nullptr)
Breaks a single segment into two at the specified point.
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.
void RotateEnd(wxPoint aPosition)
Definition: sch_line.cpp:407
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:79
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.h:139
bool IsMoving() const
Definition: eda_item.h:169
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
int Rotate(const TOOL_EVENT &aEvent)
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:85
void SetItalic(bool isItalic)
Definition: eda_text.h:186
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:146
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1372
int EditPageNumber(const TOOL_EVENT &aEvent)
int BreakWire(const TOOL_EVENT &aEvent)
virtual void MirrorVertically(int aCenter)=0
Mirror item vertically about aCenter.
TOOL_MENU & GetToolMenu()
double GetTextAngle() const
Definition: eda_text.h:181
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
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:370
EE_COLLECTOR.
Definition: ee_collectors.h:42
static TOOL_ACTION toText
Definition: ee_actions.h:130
static const KICAD_T FieldOwners[]
Definition: ee_collectors.h:51
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:122
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:345
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.h:279
void OnPageSettingsChange() override
Called when modifying the page settings.
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:145
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:100
static const KICAD_T ComponentsOnly[]
Definition: ee_collectors.h:48
virtual wxPoint GetPosition() const
Definition: eda_item.h:301
static const KICAD_T SheetsOnly[]
Definition: ee_collectors.h:49
static TOOL_ACTION mirrorH
Definition: ee_actions.h:117
wxPoint GetNearestGridPosition(const wxPoint &aPosition) const
Return the nearest aGridSize location to aPosition.
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:304
int GetTextThickness() const
Definition: eda_text.h:167
void update() override
Update menu state stub.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:285
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:125
#define TEMP_SELECTED
flag indicating that the structure has already selected
Definition: eda_item.h:114
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:214
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:165
void GuessSelectionCandidates(EE_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
void RotateStart(wxPoint aPosition)
Definition: sch_line.cpp:401
static TOOL_ACTION breakWire
Definition: ee_actions.h:131
static TOOL_ACTION mirrorV
Definition: ee_actions.h:116
static TOOL_ACTION rotateCW
Definition: ee_actions.h:114
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:77
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:70
bool IsNew() const
Definition: eda_item.h:168
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:58
static TOOL_ACTION pickerTool
Definition: actions.h:158
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:65
bool IsItalic() const
Definition: eda_text.h:187
virtual void Rotate(wxPoint aPosition)=0
Rotate the item around aPosition 90 degrees in the clockwise direction.
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...
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:270
int Duplicate(const TOOL_EVENT &aEvent)
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
static TOOL_ACTION drawSheet
Definition: ee_actions.h:86
static SELECTION_CONDITION SingleDeMorganSymbol
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
static TOOL_ACTION copy
Definition: actions.h:70
void editFieldText(SCH_FIELD *aField)
Set up handlers for various events.
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:188
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:115
int GetUnit() const
Definition: sch_symbol.h:237
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:121
AUTOPLACE_FIELDS m_AutoplaceFields
Item needs to be redrawn.
Definition: view_item.h:57
void SetFlags(STATUS_FLAGS aMask)
Definition: eda_item.h:202
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:57
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:590
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:78
#define NULL
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
BITMAP_BASE * GetImage() const
Definition: sch_bitmap.h:59
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:133
STATUS_FLAGS GetEditFlags() const
Definition: eda_item.h:207
int ShowQuasiModal()
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:443
wxString GetPageNumber() const
const wxSize & GetTextSize() const
Definition: eda_text.h:245
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:466
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:209
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:88
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetIcon(const BITMAP_OPAQUE *aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:71
Generic, UI-independent tool event.
Definition: tool_event.h:173
bool IncrementLabel(int aIncrement)
Increment the label text, if it ends with a number.
Definition: sch_text.cpp:164
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:147
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:80
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:477
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:113
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:133
static TOOL_ACTION cut
Definition: actions.h:69
SCHEMATIC & Schematic() const
void UpdateHierarchyNavigator(bool aForceUpdate=false)
Run the Hierarchy Navigator dialog.
void SaveCopyForRepeatItem(SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
EDA_ITEM * GetParent() const
Definition: eda_item.h:164
const KICAD_T rotatableItems[]
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:176
LABEL_SPIN_STYLE GetLabelSpinStyle() const
Definition: sch_text.h:233
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:44
#define STRUCT_DELETED
flag indication structures to be erased
Definition: eda_item.h:115
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:373
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:85
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:556
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:54
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_PART > & GetPartRef()
Definition: sch_symbol.h:206
virtual void Move(const wxPoint &aWhere)
bool Init() override
Init() is called once upon a registration of the tool.
static TOOL_ACTION addNeededJunctions
Definition: ee_actions.h:73
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:189
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:472
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:106
wxPoint GetPosition() const override
Definition: sch_text.h:312
virtual void PopupFor(int aMsecs)
void Rotate(wxPoint aPosition) override
Rotate the item around aPosition 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:722
int DeleteItemCursor(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:124
DIALOG_SCH_EDIT_ONE_FIELD is a the class to handle editing a single component field in the schematic ...
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:42
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:81
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool NameExists(const wxString &aSheetName)
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:60
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:102
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:308
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:219
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:230
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
static TOOL_ACTION pasteSpecial
Definition: actions.h:72
EDA_TEXT_VJUSTIFY_T
Definition: eda_text.h:68
EDA_ITEM * m_pickerItem
Definition: sch_edit_tool.h:88
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:101
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:287
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:69
virtual bool IsLocked() const
Definition: sch_item.h:270
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
int Modifier(int aMask=MD_MODIFIER_MASK) const
Definition: tool_event.h:352
static TOOL_ACTION placeLabel
Definition: ee_actions.h:83
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: eda_item.h:111
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
static bool IsDrawingLineWireOrBus(const SELECTION &aSelection)
static TOOL_ACTION editValue
Definition: ee_actions.h:120
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:111
static KICAD_T deletableItems[]
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
SCH_SHEET & Root() const
Definition: schematic.h:116
SCH_ITEM * GetRepeatItem() const
Return the item which is to be repeated with the insert key.
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:89
see class PGM_BASE
int AddItemToSel(const TOOL_EVENT &aEvent)
SCH_SCREEN * LastScreen()
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
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:208
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.
#define _(s)
Definition: 3d_actions.cpp:33
TOOL_MANAGER * getToolManager() const
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:150
static TOOL_ACTION drag
Definition: ee_actions.h:112
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
These Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which ar...
Definition: string.cpp:77
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
Function GetName returns the field name.
Definition: sch_field.cpp:505
EE_RTREE & Items()
Definition: sch_screen.h:162
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Create a functor that tests if the selected items are only of given type.
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:447
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:128
Schematic symbol object.
Definition: sch_symbol.h:79
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:68
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:144
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
wxString GetClass() const override
Return the class name.
Definition: sch_field.h:70
wxPoint Centre() const
Definition: eda_rect.h:60
int ChangeSymbols(const TOOL_EVENT &aEvent)
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:203
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:465
void Activate()
Run the tool.
wxPoint GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:601
static SELECTION_CONDITION SingleSymbolOrPower
void Rotate(wxPoint aPosition) override
Rotate the item around aPosition 90 degrees in the clockwise direction.
SCH_SHEET_PATH & GetCurrentSheet() const
static TOOL_ACTION deleteTool
Definition: actions.h:76
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:939
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:159
static TOOL_ACTION move
Definition: ee_actions.h:111
#define ENDPOINT
ends. (Used to support dragging.)
Definition: eda_item.h:112
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:48
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T)
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:312
static TOOL_ACTION toLabel
Definition: ee_actions.h:127
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:166
void SetSnapping(bool aSnap)
Definition: picker_tool.h:62
int GetConvert() const
Definition: sch_symbol.h:265
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:239
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:51
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:174
static TOOL_ACTION toHLabel
Definition: ee_actions.h:128
virtual const EDA_RECT GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:89
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:119
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the components inside new sheetpaths when a complex hierarchy is modified an...
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:248
const wxPoint GetCenter() const
Definition: eda_rect.h:109
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:84
int DoDelete(const TOOL_EVENT &aEvent)
Run the deletion tool.
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:189
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:281
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
Definition: tool_manager.h:267
void SetBold(bool aBold)
Definition: eda_text.h:189
void ConvertPart(SCH_COMPONENT *aComponent)
Definition: getpart.cpp:237
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.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:196
static TOOL_ACTION selectAll
Definition: actions.h:73
static TOOL_ACTION toGLabel
Definition: ee_actions.h:129
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:297
#define IS_NEW
New item, just created.
Definition: eda_item.h:106
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
int ConvertDeMorgan(const TOOL_EVENT &aEvent)
static TOOL_ACTION paste
Definition: actions.h:71
static const KICAD_T EditableItems[]
Definition: ee_collectors.h:46
static TOOL_ACTION duplicate
Definition: actions.h:74
int ChangeTextType(const TOOL_EVENT &aEvent)
Change a text type to another one.
void SetText(const wxString &aText)
Display a text.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:536
bool HasFlag(STATUS_FLAGS aFlag) const
Definition: eda_item.h:205
static TOOL_ACTION refreshPreview
Definition: actions.h:109
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:203
Dialog used to edit SCH_COMPONENT 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:1508
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:235
static const KICAD_T WiresOnly[]
Definition: ee_collectors.h:50
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:404
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
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.