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