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 toLabelTypes[] = { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
284  auto toLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toLabelTypes );
285 
286  static KICAD_T toHLableTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_TEXT_T, EOT };
287  auto toHLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toHLableTypes );
288 
289  static KICAD_T toGLableTypes[] = { SCH_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
290  auto toGLabelCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toGLableTypes );
291 
292  static KICAD_T toTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, EOT };
293  auto toTextlCondition = E_C::Count( 1 ) && E_C::OnlyTypes( toTextTypes );
294 
295  static KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT };
296  auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( entryTypes );
297 
298  auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
299 
300  //
301  // Add edit actions to the move tool menu
302  //
303  if( moveTool )
304  {
305  CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
306 
307  moveMenu.AddSeparator();
308  moveMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition );
309  moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition );
310  moveMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition );
311  moveMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition );
312 
313  moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
318 
319  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
320  symUnitMenu->SetTool( this );
321  m_menu.AddSubMenu( symUnitMenu );
322  moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
323 
324  moveMenu.AddSeparator();
328  moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
329 
330  moveMenu.AddSeparator();
331  moveMenu.AddItem( ACTIONS::selectAll, hasElements );
332  }
333 
334  //
335  // Add editing actions to the drawing tool menu
336  //
337  CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
338 
339  drawMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
340  drawMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
341  drawMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
342  drawMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
343 
344  drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
348  drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
350 
351  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
352  symUnitMenu2->SetTool( drawingTools );
353  drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 );
354  drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
355 
357 
358  drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
359  drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
360  drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
361  drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
362 
363  //
364  // Add editing actions to the selection tool menu
365  //
367 
368  selToolMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
369  selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
370  selToolMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
371  selToolMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
372 
373  selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
375  selToolMenu.AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
377  selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
379 
380  std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
381  symUnitMenu3->SetTool( m_selectionTool );
382  m_selectionTool->GetToolMenu().AddSubMenu( symUnitMenu3 );
383  selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
384 
388 
389  selToolMenu.AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
390  selToolMenu.AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
391  selToolMenu.AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
392  selToolMenu.AddItem( EE_ACTIONS::toText, toTextlCondition, 200 );
393  selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
394 
395  selToolMenu.AddSeparator( 300 );
396  selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
397  selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
398  selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
399  selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
400  selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
401  selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
402 
403  selToolMenu.AddSeparator( 400 );
404  selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
405 
406 
407  return true;
408 }
409 
410 
412  SCH_TEXT_T,
413  SCH_LABEL_T,
416  SCH_FIELD_T,
417  SCH_SYMBOL_T,
419  SCH_SHEET_T,
420  SCH_BITMAP_T,
423  SCH_LINE_T,
426  EOT
427 };
428 
429 
430 int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
431 {
432  bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
434 
435  if( selection.GetSize() == 0 )
436  return 0;
437 
438  SCH_ITEM* head = nullptr;
439  int principalItemCount = 0; // User-selected items (as opposed to connected wires)
440  wxPoint rotPoint;
441  bool moving = false;
442  bool connections = false;
443 
444  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
445  {
446  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
447 
448  if( item->HasFlag( TEMP_SELECTED ) )
449  continue;
450 
451  principalItemCount++;
452 
453  if( !head )
454  head = item;
455  }
456 
457  if( head && head->IsMoving() )
458  moving = true;
459 
460  if( principalItemCount == 1 )
461  {
462  rotPoint = head->GetPosition();
463 
464  if( !moving )
466 
467  switch( head->Type() )
468  {
469  case SCH_SYMBOL_T:
470  {
471  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
472 
473  if( clockwise )
475  else
477 
479  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
480 
481  break;
482  }
483 
484  case SCH_TEXT_T:
485  case SCH_LABEL_T:
486  case SCH_GLOBAL_LABEL_T:
487  case SCH_HIER_LABEL_T:
488  {
489  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
490  textItem->Rotate90( clockwise );
491  break;
492  }
493 
494  case SCH_SHEET_PIN_T:
495  {
496  // Rotate pin within parent sheet
497  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
498  SCH_SHEET* sheet = pin->GetParent();
499 
500  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
501  pin->Rotate( sheet->GetBoundingBox().GetCenter() );
502 
503  break;
504  }
505 
506  case SCH_LINE_T:
507  case SCH_BUS_BUS_ENTRY_T:
509  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
510  head->Rotate( rotPoint );
511 
512  break;
513 
514  case SCH_FIELD_T:
515  {
516  SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
517 
518  if( field->GetTextAngle() == TEXT_ANGLE_HORIZ )
519  field->SetTextAngle( TEXT_ANGLE_VERT );
520  else
521  field->SetTextAngle( TEXT_ANGLE_HORIZ );
522 
523  // Now that we're moving a field, they're no longer autoplaced.
524  static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
525 
526  break;
527  }
528 
529  case SCH_BITMAP_T:
530  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
531  head->Rotate( rotPoint );
532 
533  // The bitmap is cached in Opengl: clear the cache to redraw
535  break;
536 
537  case SCH_SHEET_T:
538  {
539  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
540  rotPoint = m_frame->GetNearestGridPosition( sheet->GetRotationCenter() );
541 
542  // Rotate the sheet on itself. Sheets do not have an anchor point.
543  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
544  sheet->Rotate( rotPoint );
545 
546  break;
547  }
548 
549  default:
550  break;
551  }
552 
553  connections = head->IsConnectable();
554  m_frame->UpdateItem( head, false, true );
555  }
556  else
557  {
558  rotPoint = m_frame->GetNearestGridPosition( (wxPoint)selection.GetCenter() );
559  }
560 
561  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
562  {
563  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
564 
565  // We've already rotated the user selected item if there was only one. We're just
566  // here to rotate the ends of wires that were attached to it.
567  if( principalItemCount == 1 && !item->HasFlag( TEMP_SELECTED ) )
568  continue;
569 
570  if( !moving )
571  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
572 
573  for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
574  {
575  if( item->Type() == SCH_LINE_T )
576  {
577  SCH_LINE* line = (SCH_LINE*) item;
578 
579  // If we are rotating more than one item, we do not have start/end
580  // points separately selected
581  if( item->HasFlag( STARTPOINT ) )
582  line->RotateStart( rotPoint );
583 
584  if( item->HasFlag( ENDPOINT ) )
585  line->RotateEnd( rotPoint );
586  }
587  else if( item->Type() == SCH_SHEET_PIN_T )
588  {
589  if( item->GetParent()->IsSelected() )
590  {
591  // parent will rotate us
592  }
593  else
594  {
595  // rotate within parent
596  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
597  SCH_SHEET* sheet = pin->GetParent();
598 
599  pin->Rotate( sheet->GetBoundingBox().GetCenter() );
600  }
601  }
602  else if( item->Type() == SCH_FIELD_T )
603  {
604  if( item->GetParent()->IsSelected() )
605  {
606  // parent will rotate us
607  }
608  else
609  {
610  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
611 
612  field->Rotate( rotPoint );
613 
614  if( field->GetTextAngle() == TEXT_ANGLE_HORIZ )
615  field->SetTextAngle( TEXT_ANGLE_VERT );
616  else
617  field->SetTextAngle( TEXT_ANGLE_HORIZ );
618 
619  // Now that we're moving a field, they're no longer autoplaced.
620  static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
621  }
622  }
623  else
624  {
625  item->Rotate( rotPoint );
626  }
627  }
628 
629  connections |= item->IsConnectable();
630  m_frame->UpdateItem( item, false, true );
631  updateItem( item, true );
632  }
633 
635 
636  if( moving )
637  {
639  }
640  else
641  {
642  if( selection.IsHover() )
644 
645  if( connections )
647 
648  m_frame->OnModify();
649  }
650 
651  return 0;
652 }
653 
654 
655 int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
656 {
658 
659  if( selection.GetSize() == 0 )
660  return 0;
661 
662  wxPoint mirrorPoint;
663  bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
664  SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
665  bool connections = false;
666  bool moving = item->IsMoving();
667 
668  if( selection.GetSize() == 1 )
669  {
670  if( !moving )
672 
673  switch( item->Type() )
674  {
675  case SCH_SYMBOL_T:
676  {
677  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
678 
679  if( vertical )
680  symbol->SetOrientation( SYM_MIRROR_X );
681  else
682  symbol->SetOrientation( SYM_MIRROR_Y );
683 
685  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
686 
687  break;
688  }
689 
690  case SCH_TEXT_T:
691  case SCH_LABEL_T:
692  case SCH_GLOBAL_LABEL_T:
693  case SCH_HIER_LABEL_T:
694  {
695  SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
696  textItem->MirrorSpinStyle( !vertical );
697  break;
698  }
699 
700  case SCH_SHEET_PIN_T:
701  {
702  // mirror within parent sheet
703  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
704  SCH_SHEET* sheet = pin->GetParent();
705 
706  if( vertical )
707  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
708  else
709  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
710 
711  break;
712  }
713 
714  case SCH_BUS_BUS_ENTRY_T:
716  if( vertical )
717  item->MirrorVertically( item->GetPosition().y );
718  else
719  item->MirrorHorizontally( item->GetPosition().x );
720  break;
721 
722  case SCH_FIELD_T:
723  {
724  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
725 
726  if( vertical )
728  else
730 
731  // Now that we're re-justifying a field, they're no longer autoplaced.
732  static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
733 
734  break;
735  }
736 
737  case SCH_BITMAP_T:
738  if( vertical )
739  item->MirrorVertically( item->GetPosition().y );
740  else
741  item->MirrorHorizontally( item->GetPosition().x );
742 
743  // The bitmap is cached in Opengl: clear the cache to redraw
745  break;
746 
747  case SCH_SHEET_T:
748  // Mirror the sheet on itself. Sheets do not have a anchor point.
749  mirrorPoint = m_frame->GetNearestHalfGridPosition( item->GetBoundingBox().Centre() );
750 
751  if( vertical )
752  item->MirrorVertically( mirrorPoint.y );
753  else
754  item->MirrorHorizontally( mirrorPoint.x );
755 
756  break;
757 
758  default:
759  break;
760  }
761 
762  connections = item->IsConnectable();
763  m_frame->UpdateItem( item, false, true );
764  }
765  else if( selection.GetSize() > 1 )
766  {
767  mirrorPoint = m_frame->GetNearestHalfGridPosition( (wxPoint)selection.GetCenter() );
768 
769  for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
770  {
771  item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
772 
773  if( !moving )
774  saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
775 
776  if( item->Type() == SCH_SHEET_PIN_T )
777  {
778  if( item->GetParent()->IsSelected() )
779  {
780  // parent will mirror us
781  }
782  else
783  {
784  // mirror within parent sheet
785  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
786  SCH_SHEET* sheet = pin->GetParent();
787 
788  if( vertical )
789  pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
790  else
791  pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
792  }
793  }
794  else if( item->Type() == SCH_TEXT_T || item->Type() == SCH_LABEL_T )
795  {
798 
799  wxPoint textMirrorPoint = mirrorPoint;
800 
801  textMirrorPoint.y += item->GetBoundingBox().GetHeight() / 2;
802  textMirrorPoint = m_frame->GetNearestHalfGridPosition( textMirrorPoint );
803 
804  if( vertical )
805  item->MirrorVertically( textMirrorPoint.y );
806  else
807  item->MirrorHorizontally( textMirrorPoint.x );
808  }
809  else
810  {
811  if( vertical )
812  item->MirrorVertically( mirrorPoint.y );
813  else
814  item->MirrorHorizontally( mirrorPoint.x );
815  }
816 
817  connections |= item->IsConnectable();
818  m_frame->UpdateItem( item, false, true );
819  }
820  }
821 
823 
824  // Update R-Tree for modified items
825  for( EDA_ITEM* selected : selection )
826  updateItem( selected, true );
827 
828  if( item->IsMoving() )
829  {
831  }
832  else
833  {
834  if( selection.IsHover() )
836 
837  if( connections )
839 
840  m_frame->OnModify();
841  }
842 
843  return 0;
844 }
845 
846 
848 {
849  SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
850 
851  if( !sourceItem )
852  return 0;
853 
855 
856  SCH_ITEM* newItem = sourceItem->Duplicate();
857  bool performDrag = false;
858 
859  // If cloning a symbol then put into 'move' mode.
860  if( newItem->Type() == SCH_SYMBOL_T )
861  {
862  wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( true );
863  newItem->Move( cursorPos - newItem->GetPosition() );
864  performDrag = true;
865  }
866  else
867  {
868  if( m_isSymbolEditor )
869  {
870  auto* cfg = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
871 
872  if( dynamic_cast<SCH_TEXT*>( newItem ) )
873  {
874  SCH_TEXT* text = static_cast<SCH_TEXT*>( newItem );
875  text->IncrementLabel( cfg->m_Repeat.label_delta );
876  }
877 
878  newItem->Move( wxPoint( Mils2iu( cfg->m_Repeat.x_step ),
879  Mils2iu( cfg->m_Repeat.y_step ) ) );
880  }
881  else
882  {
883  EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
884 
885  if( dynamic_cast<SCH_TEXT*>( newItem ) )
886  {
887  SCH_TEXT* text = static_cast<SCH_TEXT*>( newItem );
888 
889  // If incrementing tries to go below zero, tell user why the value is repeated
890 
891  if( !text->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
892  m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
893  }
894 
895  newItem->Move( wxPoint( Mils2iu( cfg->m_Drawing.default_repeat_offset_x ),
896  Mils2iu( cfg->m_Drawing.default_repeat_offset_y ) ) );
897  }
898  }
899 
900  newItem->SetFlags( IS_NEW );
901  m_frame->AddToScreen( newItem, m_frame->GetScreen() );
903 
904  // Symbols need to be handled by the move tool. The move tool will handle schematic
905  // cleanup routines
906  if( performDrag )
908 
909  newItem->ClearFlags();
910 
911  if( !performDrag && newItem->IsConnectable() )
912  {
913  EE_SELECTION new_sel;
914  new_sel.Add( newItem );
915 
917 
920  }
921 
922  m_frame->GetCanvas()->Refresh();
923  m_frame->OnModify();
924 
925  // Save newItem at the new position.
926  m_frame->SaveCopyForRepeatItem( newItem );
927 
928  return 0;
929 }
930 
931 
933 {
934  SCH_MARKER_T,
936  SCH_LINE_T,
939  SCH_TEXT_T,
940  SCH_LABEL_T,
944  SCH_SHEET_T,
946  SCH_SYMBOL_T,
947  SCH_BITMAP_T,
948  EOT
949 };
950 
951 
953 {
954  SCH_SCREEN* screen = m_frame->GetScreen();
956  bool appendToUndo = false;
957  std::vector<wxPoint> pts;
958 
959  if( items.empty() )
960  return 0;
961 
962  // Don't leave a freed pointer in the selection
964 
965  for( EDA_ITEM* item : items )
966  item->ClearFlags( STRUCT_DELETED );
967 
968  for( EDA_ITEM* item : items )
969  {
970  SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
971 
972  if( !sch_item )
973  continue;
974 
975  if( sch_item->IsConnectable() )
976  {
977  std::vector<wxPoint> tmp_pts = sch_item->GetConnectionPoints();
978  pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
979  }
980 
981  if( sch_item->Type() == SCH_JUNCTION_T )
982  {
983  sch_item->SetFlags( STRUCT_DELETED );
984  // clean up junctions at the end
985  }
986  else if( sch_item->Type() == SCH_SHEET_PIN_T )
987  {
988  SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
989  SCH_SHEET* sheet = pin->GetParent();
990 
991  if( !alg::contains( items, sheet ) )
992  {
993  pin->SetFlags( STRUCT_DELETED );
994  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
995  appendToUndo = true;
996 
997  updateItem( pin, false );
998 
999  sheet->RemovePin( pin );
1000  }
1001  }
1002  else
1003  {
1004  sch_item->SetFlags( STRUCT_DELETED );
1005  saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1006  appendToUndo = true;
1007 
1008  updateItem( sch_item, false );
1009 
1010  m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
1011 
1012  if( sch_item->Type() == SCH_SHEET_T )
1014  }
1015  }
1016 
1017  for( auto point : pts )
1018  {
1019  SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1020 
1021  if( !junction )
1022  continue;
1023 
1024  if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsJunctionNeeded( point ) )
1025  m_frame->DeleteJunction( junction, appendToUndo );
1026  }
1027 
1029 
1030  m_frame->GetCanvas()->Refresh();
1031  m_frame->OnModify();
1032 
1033  return 0;
1034 }
1035 
1036 
1037 #define HITTEST_THRESHOLD_PIXELS 5
1038 
1039 
1041 {
1042  std::string tool = aEvent.GetCommandStr().get();
1043  PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
1044 
1046  m_pickerItem = nullptr;
1047 
1048  // Deactivate other tools; particularly important if another PICKER is currently running
1049  Activate();
1050 
1051  picker->SetCursor( KICURSOR::REMOVE );
1052  picker->SetSnapping( false );
1053 
1054  picker->SetClickHandler(
1055  [this]( const VECTOR2D& aPosition ) -> bool
1056  {
1057  if( m_pickerItem )
1058  {
1060  selectionTool->UnbrightenItem( m_pickerItem );
1061  selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1063  m_pickerItem = nullptr;
1064  }
1065 
1066  return true;
1067  } );
1068 
1069  picker->SetMotionHandler(
1070  [this]( const VECTOR2D& aPos )
1071  {
1072  EE_COLLECTOR collector;
1073  collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1074  collector.Collect( m_frame->GetScreen(), deletableItems, (wxPoint) aPos );
1075 
1077  selectionTool->GuessSelectionCandidates( collector, aPos );
1078 
1079  EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1080 
1081  if( m_pickerItem != item )
1082  {
1083  if( m_pickerItem )
1084  selectionTool->UnbrightenItem( m_pickerItem );
1085 
1086  m_pickerItem = item;
1087 
1088  if( m_pickerItem )
1089  selectionTool->BrightenItem( m_pickerItem );
1090  }
1091  } );
1092 
1093  picker->SetFinalizeHandler(
1094  [this]( const int& aFinalState )
1095  {
1096  if( m_pickerItem )
1098 
1099  // Wake the selection tool after exiting to ensure the cursor gets updated
1101  } );
1102 
1103  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1104 
1105  return 0;
1106 }
1107 
1108 
1110 {
1111  // Save old symbol in undo list if not already in edit, or moving.
1112  if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1114 
1115  KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1116  wxString caption;
1117 
1118  // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1119  if( parentType == SCH_SYMBOL_T && aField->GetId() < MANDATORY_FIELDS )
1120  caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1121  else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
1122  caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1123  else
1124  caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1125 
1126  DIALOG_SCH_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1127 
1128  // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1129  if( dlg.ShowQuasiModal() != wxID_OK )
1130  return;
1131 
1132  dlg.UpdateField( aField, &m_frame->GetCurrentSheet() );
1133 
1134  if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1135  static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1136 
1137  m_frame->UpdateItem( aField, false, true );
1138  m_frame->OnModify();
1139 
1140  // This must go after OnModify() so that the connectivity graph will have been updated.
1142 }
1143 
1144 
1146 {
1147  static KICAD_T Nothing[] = { EOT };
1148  static KICAD_T CmpOrReference[] = { SCH_FIELD_LOCATE_REFERENCE_T, SCH_SYMBOL_T, EOT };
1149  static KICAD_T CmpOrValue[] = { SCH_FIELD_LOCATE_VALUE_T, SCH_SYMBOL_T, EOT };
1150  static KICAD_T CmpOrFootprint[] = { SCH_FIELD_LOCATE_FOOTPRINT_T, SCH_SYMBOL_T, EOT };
1151 
1152  KICAD_T* filter = Nothing;
1153 
1154  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1155  filter = CmpOrReference;
1156  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1157  filter = CmpOrValue;
1158  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1159  filter = CmpOrFootprint;
1160 
1162 
1163  if( selection.Size() != 1 )
1164  return 0;
1165 
1166  bool clearSelection = selection.IsHover();
1167  EDA_ITEM* item = selection.Front();
1168 
1169  if( item->Type() == SCH_SYMBOL_T )
1170  {
1171  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1172 
1173  if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1174  editFieldText( symbol->GetField( REFERENCE_FIELD ) );
1175  else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1176  editFieldText( symbol->GetField( VALUE_FIELD ) );
1177  else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1178  editFieldText( symbol->GetField( FOOTPRINT_FIELD ) );
1179  }
1180  else if( item->Type() == SCH_FIELD_T )
1181  {
1182  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1183 
1184  editFieldText( field );
1185 
1186  if( !field->IsVisible() )
1187  clearSelection = true;
1188  }
1189 
1190  if( clearSelection )
1192 
1193  return 0;
1194 }
1195 
1196 
1198 {
1200 
1201  if( selection.Empty() )
1202  return 0;
1203 
1204  for( EDA_ITEM* item : selection )
1205  {
1206  SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( item );
1207 
1208  if( !sch_item->IsNew() )
1210 
1211  sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1212  updateItem( sch_item, true );
1213  }
1214 
1215  m_frame->OnModify();
1216 
1217  if( selection.IsHover() )
1219 
1220  return 0;
1221 }
1222 
1223 
1225 {
1226  SCH_SYMBOL* selectedSymbol = nullptr;
1228 
1229  if( !selection.Empty() )
1230  selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1231 
1233 
1234  if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1235  || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1236  {
1238  }
1239 
1240  DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1241 
1242  dlg.ShowQuasiModal();
1243 
1244  return 0;
1245 }
1246 
1247 
1249 {
1251 
1252  if( selection.Empty() )
1253  return 0;
1254 
1255  SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1256 
1258  && symbol->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1259  {
1260  return 0;
1261  }
1262 
1264  && symbol->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
1265  {
1266  return 0;
1267  }
1268 
1269  if( !symbol->IsNew() )
1271 
1272  m_frame->ConvertPart( symbol );
1273 
1274  if( symbol->IsNew() )
1276 
1277  if( selection.IsHover() )
1279 
1280  return 0;
1281 }
1282 
1283 
1285 {
1287  bool clearSelection = selection.IsHover();
1288 
1289  if( selection.Empty() )
1290  {
1292  {
1294  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1295 
1296  if( ds && ds->HitTestDrawingSheetItems( getView(), (wxPoint) cursorPos ) )
1298  }
1299 
1300  return 0;
1301  }
1302 
1303  EDA_ITEM* item = selection.Front();
1304 
1305  switch( item->Type() )
1306  {
1307  case SCH_LINE_T:
1308  case SCH_BUS_WIRE_ENTRY_T:
1309  if( !selection.AllItemsHaveLineStroke() )
1310  return 0;
1311 
1312  break;
1313 
1314  case SCH_JUNCTION_T:
1315  if( !selection.AreAllItemsIdentical() )
1316  return 0;
1317 
1318  break;
1319 
1320  default:
1321  if( selection.Size() > 1 )
1322  return 0;
1323 
1324  break;
1325  }
1326 
1327  auto doTextAndLabelProps =
1328  [&]( SCH_TEXT* aText )
1329  {
1331 
1332  // Must be quasi modal for syntax help
1333  if( dlg.ShowQuasiModal() == wxID_OK )
1334  {
1336  m_frame->OnModify();
1337  }
1338  };
1339 
1340  switch( item->Type() )
1341  {
1342  case SCH_SYMBOL_T:
1343  {
1344  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1345  DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1346 
1347  // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1348  // frame. Therefore this dialog as a modal frame parent, MUST be run under
1349  // quasimodal mode for the quasimodal frame support to work. So don't use
1350  // the QUASIMODAL macros here.
1351  int retval = symbolPropsDialog.ShowQuasiModal();
1352 
1353  if( retval == SYMBOL_PROPS_EDIT_OK )
1354  {
1356  symbol->AutoAutoplaceFields( m_frame->GetScreen() );
1357 
1359  m_frame->OnModify();
1360  }
1361  else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1362  {
1364  true );
1365 
1366  editor->LoadSymbolFromSchematic( symbol );
1367 
1368  editor->Show( true );
1369  editor->Raise();
1370  }
1371  else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1372  {
1374  true );
1375 
1376  editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
1377 
1378  editor->Show( true );
1379  editor->Raise();
1380  }
1381  else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1382  {
1384  dlg.ShowQuasiModal();
1385  }
1386  else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1387  {
1389  dlg.ShowQuasiModal();
1390  }
1391  }
1392  break;
1393 
1394  case SCH_SHEET_T:
1395  {
1396  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1397  bool doClearAnnotation;
1398  bool doRefresh = false;
1399 
1400  // Keep track of existing sheet paths. EditSheet() can modify this list.
1401  // Note that we use the validity checking/repairing version here just to make sure
1402  // we've got a valid hierarchy to begin with.
1403  SCH_SHEET_LIST initial_sheetpathList( &m_frame->Schematic().Root(), true );
1404 
1405  doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1406  &doClearAnnotation );
1407 
1408  // If the sheet file is changed and new sheet contents are loaded then we have to
1409  // clear the annotations on the new content (as it may have been set from some other
1410  // sheet path reference)
1411  if( doClearAnnotation )
1412  {
1413  SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1414  // We clear annotation of new sheet paths here:
1415  screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
1416  // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1417  // path, but symbols managed by its sheet path must have their annotation cleared
1418  // because they are new:
1420  }
1421 
1422  if( doRefresh )
1423  {
1425  m_frame->GetCanvas()->Refresh();
1427  }
1428 
1429  break;
1430  }
1431 
1432  case SCH_SHEET_PIN_T:
1433  {
1434  SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1436 
1437  // QuasiModal required for help dialog
1438  if( dlg.ShowQuasiModal() == wxID_OK )
1439  {
1441  m_frame->OnModify();
1442  }
1443  }
1444  break;
1445 
1446  case SCH_TEXT_T:
1447  case SCH_LABEL_T:
1448  case SCH_GLOBAL_LABEL_T:
1449  case SCH_HIER_LABEL_T:
1450  doTextAndLabelProps( static_cast<SCH_TEXT*>( item ) );
1451  break;
1452 
1453  case SCH_FIELD_T:
1454  {
1455  SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1456  EDA_ITEM* parent = field->GetParent();
1457 
1458  if( parent->Type() == SCH_GLOBAL_LABEL_T )
1459  doTextAndLabelProps( static_cast<SCH_TEXT*>( parent ) );
1460  else
1461  editFieldText( field );
1462 
1463  if( !field->IsVisible() )
1464  clearSelection = true;
1465  }
1466  break;
1467 
1468  case SCH_BITMAP_T:
1469  {
1470  SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( item );
1471  DIALOG_IMAGE_EDITOR dlg( m_frame, bitmap->GetImage() );
1472 
1473  if( dlg.ShowModal() == wxID_OK )
1474  {
1475  // save old image in undo list if not already in edit
1476  if( bitmap->GetEditFlags() == 0 )
1478 
1479  dlg.TransferToImage( bitmap->GetImage() );
1480 
1481  // The bitmap is cached in Opengl: clear the cache in case it has become invalid
1482  getView()->RecacheAllItems();
1484  m_frame->OnModify();
1485  }
1486  }
1487  break;
1488 
1489  case SCH_LINE_T:
1490  case SCH_BUS_WIRE_ENTRY_T:
1491  {
1492  std::deque<SCH_ITEM*> strokeItems;
1493 
1494  for( EDA_ITEM* selItem : selection.Items() )
1495  {
1496  SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( selItem );
1497 
1498  if( schItem && schItem->HasLineStroke() )
1499  strokeItems.push_back( schItem );
1500  else
1501  return 0;
1502  }
1503 
1504  DIALOG_LINE_WIRE_BUS_PROPERTIES dlg( m_frame, strokeItems );
1505 
1506  if( dlg.ShowModal() == wxID_OK )
1507  {
1509  m_frame->OnModify();
1510  }
1511  }
1512  break;
1513 
1514  case SCH_JUNCTION_T:
1515  {
1516  std::deque<SCH_JUNCTION*> junctions;
1517 
1518  for( EDA_ITEM* selItem : selection.Items() )
1519  {
1520  SCH_JUNCTION* junction = dynamic_cast<SCH_JUNCTION*>( selItem );
1521 
1522  wxCHECK( junction, 0 );
1523 
1524  junctions.push_back( junction );
1525  }
1526 
1527  DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1528 
1529  if( dlg.ShowModal() == wxID_OK )
1530  {
1532  m_frame->OnModify();
1533  }
1534  }
1535  break;
1536 
1537  case SCH_MARKER_T: // These items have no properties to edit
1538  case SCH_NO_CONNECT_T:
1539  break;
1540 
1541  default: // Unexpected item
1542  wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + item->GetClass() );
1543  }
1544 
1545  updateItem( item, true );
1546 
1547  if( clearSelection )
1549 
1550  return 0;
1551 }
1552 
1553 
1555 {
1556  KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
1558  EE_SELECTION& selection = m_selectionTool->RequestSelection( allTextTypes );
1559 
1560  for( unsigned int i = 0; i < selection.GetSize(); ++i )
1561  {
1562  SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( selection.GetItem( i ) );
1563 
1564  if( text && text->Type() != convertTo )
1565  {
1566  bool selected = text->IsSelected();
1567  SCH_TEXT* newtext = nullptr;
1568  const wxPoint& position = text->GetPosition();
1569  LABEL_SPIN_STYLE orientation = text->GetLabelSpinStyle();
1570  wxString txt = UnescapeString( text->GetText() );
1571 
1572  // There can be characters in a SCH_TEXT object that can break labels so we have to
1573  // fix them here.
1574  if( text->Type() == SCH_TEXT_T )
1575  {
1576  txt.Replace( "\n", "_" );
1577  txt.Replace( "\r", "_" );
1578  txt.Replace( "\t", "_" );
1579  txt.Replace( " ", "_" );
1580  }
1581 
1582  // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
1583  if( convertTo != SCH_TEXT_T )
1584  txt = EscapeString( txt, CTX_NETNAME );
1585 
1586  switch( convertTo )
1587  {
1588  case SCH_LABEL_T: newtext = new SCH_LABEL( position, txt ); break;
1589  case SCH_GLOBAL_LABEL_T: newtext = new SCH_GLOBALLABEL( position, txt ); break;
1590  case SCH_HIER_LABEL_T: newtext = new SCH_HIERLABEL( position, txt ); break;
1591  case SCH_TEXT_T: newtext = new SCH_TEXT( position, txt ); break;
1592 
1593  default:
1594  wxFAIL_MSG( wxString::Format( "Invalid text type: %d.", convertTo ) );
1595  return 0;
1596  }
1597 
1598  // Copy the old text item settings to the new one. Justifications are not copied
1599  // because they are not used in labels. Justifications will be set to default value
1600  // in the new text item type.
1601  //
1602  newtext->SetFlags( text->GetEditFlags() );
1603  newtext->SetShape( text->GetShape() );
1604  newtext->SetLabelSpinStyle( orientation );
1605  newtext->SetTextSize( text->GetTextSize() );
1606  newtext->SetTextThickness( text->GetTextThickness() );
1607  newtext->SetItalic( text->IsItalic() );
1608  newtext->SetBold( text->IsBold() );
1609  newtext->SetIsDangling( text->IsDangling() );
1610 
1611  if( selected )
1613 
1614  if( !text->IsNew() )
1615  {
1617  saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
1618 
1620  m_frame->AddToScreen( newtext, m_frame->GetScreen() );
1621 
1622  if( convertTo == SCH_GLOBAL_LABEL_T )
1623  static_cast<SCH_GLOBALLABEL*>( newtext )->UpdateIntersheetRefProps();
1624  }
1625 
1626  if( selected )
1627  m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
1628 
1629  // Otherwise, pointer is owned by the undo stack
1630  if( text->IsNew() )
1631  delete text;
1632 
1633  if( convertTo == SCH_TEXT_T )
1634  {
1635  if( newtext->IsDangling() )
1636  {
1637  newtext->SetIsDangling( false );
1638  getView()->Update( newtext, KIGFX::REPAINT );
1639  }
1640  }
1641  else
1642  {
1644  }
1645 
1646  m_frame->OnModify();
1647  }
1648  }
1649 
1650  if( selection.IsHover() )
1652 
1653  return 0;
1654 }
1655 
1656 
1658 {
1659  wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
1661 
1662  std::vector<SCH_LINE*> lines;
1663 
1664  for( EDA_ITEM* item : selection )
1665  {
1666  if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
1667  {
1668  if( !line->IsEndPoint( cursorPos ) )
1669  lines.push_back( line );
1670  }
1671  }
1672 
1674  m_frame->StartNewUndo();
1675 
1676  for( SCH_LINE* line : lines )
1677  m_frame->BreakSegment( line, cursorPos );
1678 
1679  if( !lines.empty() )
1680  {
1681  if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) )
1682  m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false );
1683 
1685 
1686  m_frame->OnModify();
1687  m_frame->GetCanvas()->Refresh();
1688 
1690  }
1691 
1692  return 0;
1693 }
1694 
1695 
1697 {
1699  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1700 
1701  if( !sheet || !sheet->HasUndefinedPins() )
1702  return 0;
1703 
1704  if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
1705  return 0;
1706 
1708 
1709  sheet->CleanupSheet();
1710 
1711  updateItem( sheet, true );
1712  m_frame->OnModify();
1713 
1714  if( selection.IsHover() )
1716 
1717  return 0;
1718 }
1719 
1720 
1722 {
1724 
1725  if( selection.GetSize() > 1 )
1726  return 0;
1727 
1728  SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
1729 
1730  SCH_SHEET_PATH instance = m_frame->GetCurrentSheet();
1731 
1732  SCH_SCREEN* screen;
1733 
1734  if( sheet )
1735  {
1736  // When changing the page number of a selected sheet, the current screen owns the sheet.
1737  screen = m_frame->GetScreen();
1738 
1739  instance.push_back( sheet );
1740  }
1741  else
1742  {
1743  SCH_SHEET_PATH prevInstance = instance;
1744 
1745  // When change the page number in the screen, the previous screen owns the sheet.
1746  if( prevInstance.size() )
1747  {
1748  prevInstance.pop_back();
1749  screen = prevInstance.LastScreen();
1750  }
1751  else
1752  {
1753  // The root sheet and root screen are effectively the same thing.
1754  screen = m_frame->GetScreen();
1755  }
1756 
1757  sheet = m_frame->GetCurrentSheet().Last();
1758  }
1759 
1760  wxString msg;
1761  wxString sheetPath = instance.PathHumanReadable( false );
1762  wxString pageNumber = instance.GetPageNumber();
1763 
1764  msg.Printf( _( "Enter page number for sheet path%s" ),
1765  ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
1766 
1767  wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
1768 
1769  dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
1770 
1771  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
1772  return 0;
1773 
1774  m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
1775 
1776  instance.SetPageNumber( dlg.GetValue() );
1777 
1778  if( instance == m_frame->GetCurrentSheet() )
1779  {
1780  m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
1782  }
1783 
1784  m_frame->OnModify();
1785 
1786  return 0;
1787 }
1788 
1789 
1791 {
1795  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorV.MakeEvent() );
1796  Go( &SCH_EDIT_TOOL::Mirror, EE_ACTIONS::mirrorH.MakeEvent() );
1797  Go( &SCH_EDIT_TOOL::DoDelete, ACTIONS::doDelete.MakeEvent() );
1799 
1816 
1819 
1823 }
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
bool empty() const
Definition: sch_rtree.h:163
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.
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
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:347
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:61
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:199
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:362
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:123
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:675
#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:235
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:430
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:120
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:179
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:1389
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:156
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:153
TOOL_MENU & GetToolMenu()
double GetTextAngle() const
Definition: eda_text.h:174
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:372
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:134
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:237
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:444
virtual wxPoint GetPosition() const
Definition: eda_item.h:252
static const KICAD_T SheetsOnly[]
Definition: ee_collectors.h:46
static TOOL_ACTION mirrorH
Definition: ee_actions.h:119
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: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:103
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:204
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:740
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:119
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:190
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:198
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:596
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:78
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:186
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:436
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:202
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:447
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:115
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.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:154
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:177
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:158
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:191
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:472
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
int GetHeight() const
Definition: eda_rect.h:110
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:466
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:310
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:302
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:68
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:257
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.
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.
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:201
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:582
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.
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:100
bool IsJunctionNeeded(const wxPoint &aPosition, bool aNew=false) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:403
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:421
wxPoint GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:607
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:918
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:159
void SetSnapping(bool aSnap)
Definition: picker_tool.h:64
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:311
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:97
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:167
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:320
void RotateStart(const wxPoint &aCenter)
Definition: sch_line.cpp:415
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:182
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:568
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:1512
static const KICAD_T WiresOnly[]
Definition: ee_collectors.h:47
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
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.