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