KiCad PCB EDA Suite
sch_drawing_tools.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 "sch_drawing_tools.h"
26 #include "ee_selection_tool.h"
27 #include "ee_grid_helper.h"
28 #include <ee_actions.h>
29 #include <sch_edit_frame.h>
30 #include <project.h>
31 #include <id.h>
32 #include <eeschema_id.h>
33 #include <confirm.h>
34 #include <widgets/infobar.h>
35 #include <view/view_controls.h>
36 #include <view/view.h>
37 #include <sch_symbol.h>
38 #include <sch_no_connect.h>
39 #include <sch_line.h>
40 #include <sch_junction.h>
41 #include <sch_bus_entry.h>
42 #include <sch_text.h>
43 #include <sch_sheet.h>
44 #include <sch_sheet_pin.h>
45 #include <sch_bitmap.h>
46 #include <schematic.h>
47 #include <symbol_library.h>
48 #include <eeschema_settings.h>
53 #include <string_utils.h>
55 #include <wx/filedlg.h>
56 
57 
59  EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawing" ),
60  m_lastSheetPinType( PINSHEETLABEL_SHAPE::PS_INPUT ),
61  m_lastGlobalLabelShape( PINSHEETLABEL_SHAPE::PS_INPUT ),
62  m_lastTextOrientation( LABEL_SPIN_STYLE::RIGHT ),
63  m_lastTextBold( false ),
64  m_lastTextItalic( false ),
65  m_inPlaceSymbol( false ),
66  m_inPlaceImage( false ),
67  m_inSingleClickPlace( false ),
68  m_inTwoClickPlace( false ),
69  m_inDrawSheet( false )
70 {
71 }
72 
73 
75 {
77 
78  auto belowRootSheetCondition =
79  [&]( const SELECTION& aSel )
80  {
81  return m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root();
82  };
83 
84  CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
85  ctxMenu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 2 );
86 
87  return true;
88 }
89 
90 
92 {
93  // calculate the area of the canvas in pixels that create no autopan when
94  // is inside this area the mouse cursor
95  wxSize canvas_size = m_frame->GetCanvas()->GetSize();
96  EDA_RECT canvas_area( wxPoint( 0, 0 ), canvas_size );
97  const KIGFX::VC_SETTINGS& v_settings = getViewControls()->GetSettings();
98 
99  if( v_settings.m_autoPanEnabled )
100  canvas_area.Inflate( - v_settings.m_autoPanMargin );
101 
102  // Gives a margin of 2 pixels
103  canvas_area.Inflate( -2 );
104 
105  return canvas_area;
106 }
107 
108 
110 {
111  SCH_SYMBOL* symbol = aEvent.Parameter<SCH_SYMBOL*>();
113  std::vector<PICKED_SYMBOL>* historyList = nullptr;
114 
115  if( m_inPlaceSymbol )
116  return 0;
117 
119 
120  if( aEvent.IsAction( &EE_ACTIONS::placeSymbol ) )
121  {
122  historyList = &m_symbolHistoryList;
123  }
124  else if (aEvent.IsAction( &EE_ACTIONS::placePower ) )
125  {
126  historyList = &m_powerHistoryList;
127  filter.FilterPowerSymbols( true );
128  }
129  else
130  {
131  wxFAIL_MSG( "PlaceSymbol(): unexpected request" );
132  }
133 
134  std::string tool = aEvent.GetCommandStr().get();
135  m_frame->PushTool( tool );
136 
137  auto addSymbol =
138  [&]( SCH_SYMBOL* aSymbol )
139  {
140  m_frame->SaveCopyForRepeatItem( aSymbol );
141 
143  m_selectionTool->AddItemToSel( aSymbol );
144 
145  aSymbol->SetParent( m_frame->GetScreen() );
146  aSymbol->SetFlags( IS_NEW | IS_MOVING );
147  m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), aSymbol, false );
148 
149  // Set IS_MOVING again, as AddItemToScreenAndUndoList() will have cleared it.
150  aSymbol->SetFlags( IS_MOVING );
152  };
153 
154  auto setCursor =
155  [&]()
156  {
159  };
160 
161  auto cleanup =
162  [&] ()
163  {
166  symbol = nullptr;
167  };
168 
169  Activate();
170  // Must be done after Activate() so that it gets set into the correct context
171  getViewControls()->ShowCursor( true );
172  // Set initial cursor
173  setCursor();
174 
175  // Prime the pump
176  if( symbol )
177  {
178  addSymbol( symbol );
179  getViewControls()->WarpCursor( getViewControls()->GetMousePosition( false ) );
180  }
181  else if( !aEvent.IsReactivate() )
182  {
184  }
185 
186  // Main loop: keep receiving events
187  while( TOOL_EVENT* evt = Wait() )
188  {
189  setCursor();
190  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
191 
192  if( evt->IsCancelInteractive() )
193  {
194  if( symbol )
195  {
196  cleanup();
197  }
198  else
199  {
200  m_frame->PopTool( tool );
201  break;
202  }
203  }
204  else if( evt->IsActivate() )
205  {
206  if( symbol && evt->IsMoveTool() )
207  {
208  // we're already moving our own item; ignore the move tool
209  evt->SetPassEvent( false );
210  continue;
211  }
212 
213  if( symbol )
214  {
215  m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel symbol creation." ) );
216  evt->SetPassEvent( false );
217  continue;
218  }
219 
220  if( evt->IsMoveTool() )
221  {
222  // leave ourselves on the stack so we come back after the move
223  break;
224  }
225  else
226  {
227  m_frame->PopTool( tool );
228  break;
229  }
230  }
231  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
232  {
233  if( !symbol )
234  {
236 
237  // Store the mouse position: if it is outside the canvas,
238  // (happens when clicking on a toolbar tool) one cannot
239  // use the last stored cursor position to place the new symbol
240  // (Current mouse pos after closing the dialog will be used)
242  VECTOR2D initialMousePos = controls->GetMousePosition(false);
243  // Build the rectangle area acceptable to move the cursor without
244  // having an auto-pan
245  EDA_RECT canvas_area = GetCanvasFreeAreaPixels();
246 
247  // Pick the footprint to be placed
248  bool footprintPreviews = m_frame->eeconfig()->m_Appearance.footprint_preview;
249  PICKED_SYMBOL sel = m_frame->PickSymbolFromLibTree( &filter, *historyList, true,
250  1, 1, footprintPreviews );
251  // Restore cursor position after closing the dialog,
252  // but only if it has meaning (i.e inside the canvas)
253  VECTOR2D newMousePos = controls->GetMousePosition(false);
254 
255  if( canvas_area.Contains( wxPoint( initialMousePos ) ) )
256  controls->WarpCursor( controls->GetCursorPosition(), true );
257  else if( !canvas_area.Contains( wxPoint( newMousePos ) ) )
258  // The mouse is outside the canvas area, after closing the dialog,
259  // thus can creating autopan issues. Warp the mouse to the canvas center
260  controls->WarpCursor( canvas_area.Centre(), false );
261 
262  LIB_SYMBOL* libSymbol = sel.LibId.IsValid() ?
263  m_frame->GetLibSymbol( sel.LibId ) : nullptr;
264 
265  if( !libSymbol )
266  continue;
267 
268  wxPoint pos( cursorPos );
269  symbol = new SCH_SYMBOL( *libSymbol, &m_frame->GetCurrentSheet(), sel, pos );
270  addSymbol( symbol );
271 
272  // Update cursor now that we have a symbol
273  setCursor();
274  }
275  else
276  {
278  symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
279 
280  symbol->ClearEditFlags();
281 
284 
285  m_view->Update( symbol );
286  m_frame->GetScreen()->Update( symbol );
287  m_frame->OnModify();
288 
289  SCH_SYMBOL* nextSymbol = nullptr;
290 
293  {
294  int new_unit = symbol->GetUnit();
295 
297  && symbol->GetUnit() < symbol->GetUnitCount() )
298  {
299  new_unit++;
300  }
301  else
302  {
303  new_unit = 1;
304  }
305 
306  // We are either stepping to the next unit or next symbol
307  if( m_frame->eeconfig()->m_SymChooserPanel.keep_symbol || new_unit > 1 )
308  {
309  nextSymbol = static_cast<SCH_SYMBOL*>( symbol->Duplicate() );
310  nextSymbol->SetUnit( new_unit );
311  nextSymbol->SetUnitSelection( new_unit );
312 
313  addSymbol( nextSymbol );
314  }
315  }
316 
317  symbol = nextSymbol;
318  }
319  }
320  else if( evt->IsClick( BUT_RIGHT ) )
321  {
322  // Warp after context menu only if dragging...
323  if( !symbol )
325 
327  }
328  else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
329  {
330  if( evt->GetCommandId().get() >= ID_POPUP_SCH_SELECT_UNIT_CMP
331  && evt->GetCommandId().get() <= ID_POPUP_SCH_SELECT_UNIT_SYM_MAX )
332  {
333  int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
334 
335  if( symbol )
336  {
337  m_frame->SelectUnit( symbol, unit );
339  }
340  }
341  }
342  else if( symbol && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
343  {
344  symbol->SetPosition( (wxPoint)cursorPos );
345  m_view->Update( symbol );
346  }
347  else if( symbol && evt->IsAction( &ACTIONS::doDelete ) )
348  {
349  cleanup();
350  }
351  else
352  {
353  evt->SetPassEvent();
354  }
355 
356  // Enable autopanning and cursor capture only when there is a symbol to be placed
357  getViewControls()->SetAutoPan( symbol != nullptr );
358  getViewControls()->CaptureCursor( symbol != nullptr );
359  }
360 
361  getViewControls()->SetAutoPan( false );
362  getViewControls()->CaptureCursor( false );
364 
365  return 0;
366 }
367 
368 
370 {
371  SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>();
372  bool immediateMode = image;
373  VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
374 
375  if( m_inPlaceImage )
376  return 0;
377 
379 
381 
382  // Add all the drawable symbols to preview
383  if( image )
384  {
385  image->SetPosition( (wxPoint)cursorPos );
386  m_view->ClearPreview();
387  m_view->AddToPreview( image->Clone() );
388  }
389 
390  std::string tool = aEvent.GetCommandStr().get();
391  m_frame->PushTool( tool );
392  auto setCursor =
393  [&]()
394  {
395  if( image )
397  else
399  };
400 
401  auto cleanup =
402  [&] ()
403  {
405  m_view->ClearPreview();
406  delete image;
407  image = nullptr;
408  };
409 
410  Activate();
411  // Must be done after Activate() so that it gets set into the correct context
412  getViewControls()->ShowCursor( true );
413  // Set initial cursor
414  setCursor();
415 
416  // Prime the pump
417  if( image )
419  else if( !aEvent.IsReactivate() )
421 
422  // Main loop: keep receiving events
423  while( TOOL_EVENT* evt = Wait() )
424  {
425  setCursor();
426  cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
427 
428  if( evt->IsCancelInteractive() )
429  {
430  if( image )
431  {
432  cleanup();
433  }
434  else
435  {
436  m_frame->PopTool( tool );
437  break;
438  }
439 
440  if( immediateMode )
441  {
442  m_frame->PopTool( tool );
443  break;
444  }
445  }
446  else if( evt->IsActivate() )
447  {
448  if( image && evt->IsMoveTool() )
449  {
450  // we're already moving our own item; ignore the move tool
451  evt->SetPassEvent( false );
452  continue;
453  }
454 
455  if( image )
456  {
457  m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel image creation." ) );
458  evt->SetPassEvent( false );
459  continue;
460  }
461 
462  if( evt->IsMoveTool() )
463  {
464  // leave ourselves on the stack so we come back after the move
465  break;
466  }
467  else
468  {
469  m_frame->PopTool( tool );
470  break;
471  }
472  }
473  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
474  {
475  if( !image )
476  {
478 
479  // Store the mouse position: if it is outside the canvas,
480  // (happens when clicking on a toolbar tool) one cannot
481  // use the last stored cursor position to place the new symbol
482  // (Current mouse pos after closing the dialog will be used)
484  VECTOR2D initialMousePos = controls->GetMousePosition(false);
485 
486  // Build the rectangle area acceptable to move the cursor without
487  // having an auto-pan
488  EDA_RECT canvas_area = GetCanvasFreeAreaPixels();
489 
490  wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
491  _( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(),
492  wxFD_OPEN );
493 
494  if( dlg.ShowModal() != wxID_OK )
495  continue;
496 
497  // Restore cursor position after closing the dialog,
498  // but only if it has meaning (i.e inside the canvas)
499  VECTOR2D newMousePos = controls->GetMousePosition( false );
500 
501  if( canvas_area.Contains( wxPoint( initialMousePos ) ) )
502  controls->WarpCursor( controls->GetCursorPosition(), true );
503  else if( !canvas_area.Contains( wxPoint( newMousePos ) ) )
504  // The mouse is outside the canvas area, after closing the dialog,
505  // thus can creating autopan issues. Warp the mouse to the canvas center
506  controls->WarpCursor( canvas_area.Centre(), false );
507 
508  cursorPos = controls->GetMousePosition( true );
509 
510  wxString fullFilename = dlg.GetPath();
511 
512  if( wxFileExists( fullFilename ) )
513  image = new SCH_BITMAP( (wxPoint)cursorPos );
514 
515  if( !image || !image->ReadImageFile( fullFilename ) )
516  {
517  wxMessageBox( _( "Could not load image from '%s'." ), fullFilename );
518  delete image;
519  image = nullptr;
520  continue;
521  }
522 
523  image->SetFlags( IS_NEW | IS_MOVING );
524 
526 
527  m_view->ClearPreview();
528  m_view->AddToPreview( image->Clone() );
529  m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
530 
532 
533  getViewControls()->SetCursorPosition( cursorPos, false );
534  setCursor();
535  }
536  else
537  {
539  image = nullptr;
541 
542  m_view->ClearPreview();
543 
544  if( immediateMode )
545  {
546  m_frame->PopTool( tool );
547  break;
548  }
549  }
550  }
551  else if( evt->IsClick( BUT_RIGHT ) )
552  {
553  // Warp after context menu only if dragging...
554  if( !image )
556 
558  }
559  else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
560  {
561  image->SetPosition( (wxPoint)cursorPos );
562  m_view->ClearPreview();
563  m_view->AddToPreview( image->Clone() );
564  m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
565  }
566  else if( image && evt->IsAction( &ACTIONS::doDelete ) )
567  {
568  cleanup();
569  }
570  else
571  {
572  evt->SetPassEvent();
573  }
574 
575  // Enable autopanning and cursor capture only when there is an image to be placed
576  getViewControls()->SetAutoPan( image != nullptr );
577  getViewControls()->CaptureCursor( image != nullptr );
578  }
579 
580  getViewControls()->SetAutoPan( false );
581  getViewControls()->CaptureCursor( false );
583 
584  return 0;
585 }
586 
587 
589 {
590  wxPoint cursorPos;
591  KICAD_T type = aEvent.Parameter<KICAD_T>();
594  SCH_ITEM* previewItem;
595  bool loggedInfoBarError = false;
596 
598  return 0;
599 
601 
602  if( type == SCH_JUNCTION_T && aEvent.HasPosition() )
603  {
604  EE_SELECTION& selection = m_selectionTool->GetSelection();
605  SCH_LINE* wire = dynamic_cast<SCH_LINE*>( selection.Front() );
606 
607  if( wire )
608  {
609  SEG seg( wire->GetStartPoint(), wire->GetEndPoint() );
610  VECTOR2I nearest = seg.NearestPoint( getViewControls()->GetCursorPosition() );
611  getViewControls()->SetCrossHairCursorPosition( nearest, false );
612  getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
613  }
614  }
615 
616  switch( type )
617  {
618  case SCH_NO_CONNECT_T:
619  previewItem = new SCH_NO_CONNECT( cursorPos );
620  previewItem->SetParent( m_frame->GetScreen() );
621  break;
622 
623  case SCH_JUNCTION_T:
624  previewItem = new SCH_JUNCTION( cursorPos );
625  previewItem->SetParent( m_frame->GetScreen() );
626  break;
627 
629  previewItem = new SCH_BUS_WIRE_ENTRY( cursorPos );
630  previewItem->SetParent( m_frame->GetScreen() );
631  break;
632 
633  case SCH_SHEET_PIN_T:
634  {
635  EE_SELECTION& selection = m_selectionTool->GetSelection();
636  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( selection.Front() );
637 
638  if( !sheet )
639  return 0;
640 
641  SCH_HIERLABEL* label = importHierLabel( sheet );
642 
643  if( !label )
644  {
645  m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
646  m_statusPopup->SetText( _( "No new hierarchical labels found." ) );
647  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
648  m_statusPopup->PopupFor( 2000 );
649  return 0;
650  }
651 
652  previewItem = createSheetPin( sheet, label );
653  }
654  break;
655 
656  default:
657  wxASSERT_MSG( false, "Unknown item type in SCH_DRAWING_TOOLS::SingleClickPlace" );
658  return 0;
659  }
660 
662 
663  cursorPos = static_cast<wxPoint>( aEvent.HasPosition() ?
664  aEvent.Position() :
665  controls->GetMousePosition() );
666 
667  std::string tool = aEvent.GetCommandStr().get();
668  m_frame->PushTool( tool );
669 
670  auto setCursor =
671  [&]()
672  {
674  };
675 
676  Activate();
677  // Must be done after Activate() so that it gets set into the correct context
678  getViewControls()->ShowCursor( true );
679  // Set initial cursor
680  setCursor();
681 
682  m_view->ClearPreview();
683  m_view->AddToPreview( previewItem->Clone() );
684 
685  // Prime the pump
686  if( aEvent.HasPosition() && type != SCH_SHEET_PIN_T )
688  else
690 
691  // Main loop: keep receiving events
692  while( TOOL_EVENT* evt = Wait() )
693  {
694  setCursor();
695  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
696  grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
697 
698  cursorPos = evt->IsPrime() ? (wxPoint) evt->Position()
699  : (wxPoint) controls->GetMousePosition();
700 
701  cursorPos = wxPoint( grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr ) );
702  controls->ForceCursorPosition( true, cursorPos );
703 
704  if( evt->IsCancelInteractive() )
705  {
706  m_frame->PopTool( tool );
707  break;
708  }
709  else if( evt->IsActivate() )
710  {
711  if( evt->IsMoveTool() )
712  {
713  // leave ourselves on the stack so we come back after the move
714  break;
715  }
716  else
717  {
718  m_frame->PopTool( tool );
719  break;
720  }
721  }
722  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
723  {
724  if( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) )
725  {
726  if( type == SCH_JUNCTION_T )
727  {
728  if( !m_frame->GetScreen()->IsJunctionNeeded( cursorPos ) )
729  {
730  m_frame->ShowInfoBarError( _( "Junction location contains no joinable "
731  "wires and/or pins." ) );
732  loggedInfoBarError = true;
733  continue;
734  }
735  else if( loggedInfoBarError )
736  {
737  m_frame->GetInfoBar()->Dismiss();
738  }
739  }
740 
741  SCH_ITEM* newItem = static_cast<SCH_ITEM*>( previewItem->Clone() );
742  newItem->SetPosition( cursorPos );
743  newItem->SetFlags( IS_NEW );
744 
745  m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), newItem, false );
746 
747  if( type == SCH_JUNCTION_T )
749  else
751 
752  m_frame->OnModify();
753  }
754 
755  if( evt->IsDblClick( BUT_LEFT ) || type == SCH_SHEET_PIN_T ) // Finish tool.
756  {
757  m_frame->PopTool( tool );
758  break;
759  }
760  }
761  else if( evt->IsClick( BUT_RIGHT ) )
762  {
764  }
765  else if( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() )
766  {
767  previewItem->SetPosition( (wxPoint)cursorPos );
768  m_view->ClearPreview();
769  m_view->AddToPreview( previewItem->Clone() );
770  }
771  else if( evt->Category() == TC_COMMAND )
772  {
773  if( ( type == SCH_BUS_WIRE_ENTRY_T )
774  && ( evt->IsAction( &EE_ACTIONS::rotateCW )
775  || evt->IsAction( &EE_ACTIONS::rotateCCW )
776  || evt->IsAction( &EE_ACTIONS::mirrorV )
777  || evt->IsAction( &EE_ACTIONS::mirrorH ) ) )
778  {
779  SCH_BUS_ENTRY_BASE* busItem = static_cast<SCH_BUS_ENTRY_BASE*>( previewItem );
780 
781  // The bus entries only rotate in one direction
782  if( evt->IsAction( &EE_ACTIONS::rotateCW )
783  || evt->IsAction( &EE_ACTIONS::rotateCCW ) )
784  {
785  busItem->Rotate( busItem->GetPosition() );
786  }
787  else if( evt->IsAction( &EE_ACTIONS::mirrorV ) )
788  {
789  busItem->MirrorVertically( busItem->GetPosition().x );
790  }
791  else if( evt->IsAction( &EE_ACTIONS::mirrorH ) )
792  {
793  busItem->MirrorHorizontally( busItem->GetPosition().y );
794  }
795 
796  m_view->ClearPreview();
797  m_view->AddToPreview( previewItem->Clone() );
798  }
799  else if( evt->IsAction( &EE_ACTIONS::properties ) )
800  {
801  switch( type )
802  {
804  {
805  std::deque<SCH_ITEM*> strokeItems;
806  strokeItems.push_back( previewItem );
807 
808  DIALOG_LINE_WIRE_BUS_PROPERTIES dlg( m_frame, strokeItems );
809 
810  if( dlg.ShowModal() == wxID_OK )
811  {
813  m_frame->OnModify();
814  }
815  }
816  break;
817 
818  case SCH_JUNCTION_T:
819  {
820  std::deque<SCH_JUNCTION*> junctions;
821  junctions.push_back( static_cast<SCH_JUNCTION*>( previewItem ) );
822 
823  DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
824 
825  if( dlg.ShowModal() == wxID_OK )
826  {
828  m_frame->OnModify();
829  }
830  }
831  break;
832  default:
833  // Do nothing
834  break;
835  }
836 
837  m_view->ClearPreview();
838  m_view->AddToPreview( previewItem->Clone() );
839  }
840  else
841  {
842  evt->SetPassEvent();
843  }
844  }
845  else
846  {
847  evt->SetPassEvent();
848  }
849  }
850 
851  delete previewItem;
852  m_view->ClearPreview();
853 
855  controls->ForceCursorPosition( false );
856 
857  return 0;
858 }
859 
860 
861 SCH_TEXT* SCH_DRAWING_TOOLS::createNewText( const VECTOR2I& aPosition, int aType )
862 {
863  SCHEMATIC* schematic = getModel<SCHEMATIC>();
864  SCHEMATIC_SETTINGS& settings = schematic->Settings();
865  SCH_TEXT* textItem = nullptr;
866 
867  switch( aType )
868  {
869  case LAYER_NOTES:
870  textItem = new SCH_TEXT( (wxPoint) aPosition );
871  break;
872 
873  case LAYER_LOCLABEL:
874  textItem = new SCH_LABEL( (wxPoint) aPosition );
875  break;
876 
877  case LAYER_HIERLABEL:
878  textItem = new SCH_HIERLABEL( (wxPoint) aPosition );
879  textItem->SetShape( m_lastGlobalLabelShape );
880  break;
881 
882  case LAYER_GLOBLABEL:
883  textItem = new SCH_GLOBALLABEL( (wxPoint) aPosition );
884  textItem->SetShape( m_lastGlobalLabelShape );
885 
886  if( settings.m_IntersheetRefsShow )
887  static_cast<SCH_GLOBALLABEL*>( textItem )->GetIntersheetRefs()->SetVisible( true );
888 
889  break;
890 
891  default:
892  wxFAIL_MSG( "SCH_EDIT_FRAME::CreateNewText() unknown layer type" );
893  return nullptr;
894  }
895 
896  textItem->SetParent( schematic );
897  textItem->SetBold( m_lastTextBold );
898  textItem->SetItalic( m_lastTextItalic );
900  textItem->SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
901  textItem->SetFlags( IS_NEW | IS_MOVING );
902 
903  DIALOG_TEXT_AND_LABEL_PROPERTIES dlg( m_frame, textItem );
904 
905  // Must be quasi modal for syntax help
906  if( dlg.ShowQuasiModal() != wxID_OK || NoPrintableChars( textItem->GetText() ) )
907  {
908  delete textItem;
909  return nullptr;
910  }
911 
912  m_lastTextBold = textItem->IsBold();
913  m_lastTextItalic = textItem->IsItalic();
915 
916  if( textItem->Type() == SCH_GLOBAL_LABEL_T || textItem->Type() == SCH_HIER_LABEL_T )
917  m_lastGlobalLabelShape = textItem->GetShape();
918 
919  return textItem;
920 }
921 
922 
924 {
925  if( !aSheet->GetScreen() )
926  return nullptr;
927 
928  for( EDA_ITEM* item : aSheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T ) )
929  {
930  SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
931 
932  /* A global label has been found: check if there a corresponding sheet label. */
933  if( !aSheet->HasPin( label->GetText() ) )
934  return label;
935  }
936 
937  return nullptr;
938 }
939 
940 
942 {
943  SCHEMATIC_SETTINGS& settings = aSheet->Schematic()->Settings();
944  wxString text;
945  SCH_SHEET_PIN* sheetPin;
946 
947  if( aLabel )
948  {
949  text = aLabel->GetText();
950  m_lastSheetPinType = aLabel->GetShape();
951  }
952 
953  sheetPin = new SCH_SHEET_PIN( aSheet, wxPoint( 0, 0 ), text );
954  sheetPin->SetFlags( IS_NEW );
955  sheetPin->SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
956  sheetPin->SetShape( m_lastSheetPinType );
957 
958  if( !aLabel )
959  {
960  DIALOG_SHEET_PIN_PROPERTIES dlg( m_frame, sheetPin );
961 
962  if( dlg.ShowModal() != wxID_OK || NoPrintableChars( sheetPin->GetText() ) )
963  {
964  delete sheetPin;
965  return nullptr;
966  }
967  }
968 
969  m_lastSheetPinType = sheetPin->GetShape();
970 
971  sheetPin->SetPosition( (wxPoint) getViewControls()->GetCursorPosition() );
972 
973  return sheetPin;
974 }
975 
976 
978 {
979  SCH_ITEM* item = nullptr;
982 
983  if( m_inTwoClickPlace )
984  return 0;
985 
987 
988  bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText );
989  bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel );
990  bool isHierLabel = aEvent.IsAction( &EE_ACTIONS::placeHierLabel );
991  bool isNetLabel = aEvent.IsAction( &EE_ACTIONS::placeLabel );
992  bool isSheetPin = aEvent.IsAction( &EE_ACTIONS::importSheetPin );
993  int snapLayer = isText ? LAYER_GRAPHICS : LAYER_CONNECTABLE;
994 
996 
997  std::string tool = aEvent.GetCommandStr().get();
998  m_frame->PushTool( tool );
999  auto setCursor =
1000  [&]()
1001  {
1002  if( item )
1004  else if( isText )
1006  else if( isGlobalLabel )
1008  else if( isNetLabel )
1010  else if( isHierLabel )
1012  else
1014  };
1015 
1016  auto updatePreview =
1017  [&]()
1018  {
1019  m_view->ClearPreview();
1020  m_view->AddToPreview( item->Clone() );
1021  item->RunOnChildren( [&]( SCH_ITEM* aChild )
1022  {
1023  m_view->AddToPreview( aChild->Clone() );
1024  } );
1025  };
1026 
1027  auto cleanup =
1028  [&]()
1029  {
1031  m_view->ClearPreview();
1032  delete item;
1033  item = nullptr;
1034  };
1035 
1036  Activate();
1037  // Must be done after Activate() so that it gets set into the correct context
1038  controls->ShowCursor( true );
1039  // Set initial cursor
1040  setCursor();
1041 
1042  // Prime the pump if the tool isn't being re-activated
1043  if( aEvent.HasPosition() || ( !aEvent.IsReactivate()
1044  && ( isText || isGlobalLabel || isHierLabel || isNetLabel ) ) )
1045  {
1047  }
1048 
1049  // Main loop: keep receiving events
1050  while( TOOL_EVENT* evt = Wait() )
1051  {
1052  setCursor();
1053  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1054  grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1055 
1056  VECTOR2I cursorPos = evt->IsPrime() ? evt->Position() : controls->GetMousePosition();
1057  cursorPos = grid.BestSnapAnchor( cursorPos, snapLayer, item );
1058  controls->ForceCursorPosition( true, cursorPos );
1059 
1060  if( evt->IsCancelInteractive() )
1061  {
1062  if( item )
1063  {
1064  cleanup();
1065  }
1066  else
1067  {
1068  m_frame->PopTool( tool );
1069  break;
1070  }
1071  }
1072  else if( evt->IsActivate() )
1073  {
1074  if( item && evt->IsMoveTool() )
1075  {
1076  // we're already moving our own item; ignore the move tool
1077  evt->SetPassEvent( false );
1078  continue;
1079  }
1080 
1081  if( item )
1082  {
1083  m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel item creation." ) );
1084  evt->SetPassEvent( false );
1085  continue;
1086  }
1087 
1088  if( evt->IsPointEditor() )
1089  {
1090  // don't exit (the point editor runs in the background)
1091  }
1092  else if( evt->IsMoveTool() )
1093  {
1094  break;
1095  }
1096  else
1097  {
1098  m_frame->PopTool( tool );
1099  break;
1100  }
1101  }
1102  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1103  {
1104  // First click creates...
1105  if( !item )
1106  {
1108 
1109  if( isText )
1110  {
1111  item = createNewText( cursorPos, LAYER_NOTES );
1112  }
1113  else if( isGlobalLabel )
1114  {
1115  item = createNewText( cursorPos, LAYER_GLOBLABEL );
1116  }
1117  else if( isHierLabel )
1118  {
1119  item = createNewText( cursorPos, LAYER_HIERLABEL );
1120  }
1121  else if( isNetLabel )
1122  {
1123  item = createNewText( cursorPos, LAYER_LOCLABEL );
1124  }
1125  else if( isSheetPin )
1126  {
1127  EDA_ITEM* i;
1128  SCH_HIERLABEL* label = nullptr;
1129  SCH_SHEET* sheet = nullptr;
1130 
1131  if( m_selectionTool->SelectPoint( cursorPos, EE_COLLECTOR::SheetsOnly, &i ) )
1132  sheet = dynamic_cast<SCH_SHEET*>( i );
1133 
1135 
1136  if( !sheet )
1137  {
1138  m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
1139  m_statusPopup->SetText( _( "Click over a sheet." ) );
1140  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
1141  m_statusPopup->PopupFor( 2000 );
1142  item = nullptr;
1143  }
1144  else
1145  {
1146  label = importHierLabel( sheet );
1147 
1148  if( !label )
1149  {
1150  m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
1151  m_statusPopup->SetText( _( "No new hierarchical labels found." ) );
1152  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
1153  m_statusPopup->PopupFor( 2000 );
1154  item = nullptr;
1155  }
1156  else
1157  {
1158  item = createSheetPin( sheet, label );
1159  }
1160  }
1161  }
1162 
1163  // Restore cursor after dialog
1164  controls->WarpCursor( controls->GetCursorPosition(), true );
1165 
1166  if( item )
1167  {
1168  item->SetFlags( IS_NEW | IS_MOVING );
1169  item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
1170  updatePreview();
1171 
1172  m_selectionTool->AddItemToSel( item );
1173 
1174  // update the cursor so it looks correct before another event
1175  setCursor();
1176  }
1177 
1178  controls->SetCursorPosition( cursorPos, false );
1179  }
1180  else // ... and second click places:
1181  {
1182  item->ClearFlags( IS_MOVING );
1184  false );
1185  item = nullptr;
1186 
1187  m_view->ClearPreview();
1188  }
1189  }
1190  else if( evt->IsClick( BUT_RIGHT ) )
1191  {
1192  // Warp after context menu only if dragging...
1193  if( !item )
1195 
1197  }
1198  else if( item && evt->IsSelectionEvent() )
1199  {
1200  // This happens if our text was replaced out from under us by ConvertTextType()
1201  EE_SELECTION& selection = m_selectionTool->GetSelection();
1202 
1203  if( selection.GetSize() == 1 )
1204  {
1205  item = (SCH_ITEM*) selection.Front();
1206  updatePreview();
1207  }
1208  else
1209  {
1210  item = nullptr;
1211  }
1212  }
1213  else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
1214  {
1215  item->SetPosition( (wxPoint) cursorPos );
1216  item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
1217  updatePreview();
1218  }
1219  else if( item && evt->IsAction( &ACTIONS::doDelete ) )
1220  {
1221  cleanup();
1222  }
1223  else
1224  {
1225  evt->SetPassEvent();
1226  }
1227 
1228  // Enable autopanning and cursor capture only when there is an item to be placed
1229  controls->SetAutoPan( item != nullptr );
1230  controls->CaptureCursor( item != nullptr );
1231  }
1232 
1233  controls->SetAutoPan( false );
1234  controls->CaptureCursor( false );
1235  controls->ForceCursorPosition( false );
1237  return 0;
1238 }
1239 
1240 
1242 {
1243  SCH_SHEET* sheet = nullptr;
1244 
1245  if( m_inDrawSheet )
1246  return 0;
1247 
1248  REENTRANCY_GUARD guard( &m_inDrawSheet );
1249 
1251 
1252  std::string tool = aEvent.GetCommandStr().get();
1253  m_frame->PushTool( tool );
1254 
1255  auto setCursor =
1256  [&]()
1257  {
1259  };
1260 
1261  auto cleanup =
1262  [&] ()
1263  {
1265  m_view->ClearPreview();
1266  delete sheet;
1267  sheet = nullptr;
1268  };
1269 
1270  Activate();
1271  // Must be done after Activate() so that it gets set into the correct context
1272  getViewControls()->ShowCursor( true );
1273  // Set initial cursor
1274  setCursor();
1275 
1276  // Prime the pump
1277  if( aEvent.HasPosition() )
1279 
1280  // Main loop: keep receiving events
1281  while( TOOL_EVENT* evt = Wait() )
1282  {
1283  setCursor();
1284 
1285  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
1286 
1287  if( evt->IsCancelInteractive() )
1288  {
1289  if( sheet )
1290  {
1291  cleanup();
1292  }
1293  else
1294  {
1295  m_frame->PopTool( tool );
1296  break;
1297  }
1298  }
1299  else if( evt->IsActivate() )
1300  {
1301  if( sheet && evt->IsMoveTool() )
1302  {
1303  // we're already drawing our own item; ignore the move tool
1304  evt->SetPassEvent( false );
1305  continue;
1306  }
1307 
1308  if( sheet )
1309  {
1310  m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel sheet creation." ) );
1311  evt->SetPassEvent( false );
1312  continue;
1313  }
1314 
1315  if( evt->IsPointEditor() )
1316  {
1317  // don't exit (the point editor runs in the background)
1318  }
1319  else if( evt->IsMoveTool() )
1320  {
1321  // leave ourselves on the stack so we come back after the move
1322  break;
1323  }
1324  else
1325  {
1326  m_frame->PopTool( tool );
1327  break;
1328  }
1329  }
1330  else if( !sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) )
1331  {
1333 
1335 
1336  sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(),
1337  static_cast<wxPoint>( cursorPos ) );
1338  sheet->SetFlags( IS_NEW | IS_RESIZING );
1339  sheet->SetScreen( nullptr );
1340  sheet->SetBorderWidth( Mils2iu( cfg->m_Drawing.default_line_thickness ) );
1343  sheet->GetFields()[ SHEETNAME ].SetText( "Untitled Sheet" );
1344  sheet->GetFields()[ SHEETFILENAME ].SetText( "untitled." + KiCadSchematicFileExtension );
1345  sizeSheet( sheet, cursorPos );
1346 
1347  m_view->ClearPreview();
1348  m_view->AddToPreview( sheet->Clone() );
1349  }
1350  else if( sheet && ( evt->IsClick( BUT_LEFT )
1351  || evt->IsDblClick( BUT_LEFT )
1352  || evt->IsAction( &EE_ACTIONS::finishSheet ) ) )
1353  {
1354  m_view->ClearPreview();
1355  getViewControls()->SetAutoPan( false );
1356  getViewControls()->CaptureCursor( false );
1357 
1358  // Find the list of paths in the hierarchy that refer to the destination sheet where
1359  // the new sheet will be drawn
1360  SCH_SCREEN* currentScreen = m_frame->GetCurrentSheet().LastScreen();
1361  SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets();
1362  SCH_SHEET_LIST instances = hierarchy.FindAllSheetsForScreen( currentScreen );
1363  instances.SortByPageNumbers();
1364 
1365  int pageNum = static_cast<int>( hierarchy.size() ) + 1;
1366 
1367  // Set a page number for all the instances of the new sheet in the hierarchy
1368  for( SCH_SHEET_PATH& instance : instances )
1369  {
1370  SCH_SHEET_PATH sheetPath = instance;
1371  sheetPath.push_back( sheet );
1372  sheet->AddInstance( sheetPath.Path() );
1373  sheet->SetPageNumber( sheetPath, wxString::Format( "%d", pageNum++ ) );
1374  }
1375 
1376  if( m_frame->EditSheetProperties( static_cast<SCH_SHEET*>( sheet ),
1377  &m_frame->GetCurrentSheet(), nullptr ) )
1378  {
1379  sheet->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
1380 
1381  m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), sheet, false );
1383  m_selectionTool->AddItemToSel( sheet );
1384  }
1385  else
1386  {
1387  delete sheet;
1388  }
1389 
1390  sheet = nullptr;
1391  }
1392  else if( sheet && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
1393  {
1394  sizeSheet( sheet, cursorPos );
1395  m_view->ClearPreview();
1396  m_view->AddToPreview( sheet->Clone() );
1397  }
1398  else if( evt->IsClick( BUT_RIGHT ) )
1399  {
1400  // Warp after context menu only if dragging...
1401  if( !sheet )
1403 
1405  }
1406  else
1407  {
1408  evt->SetPassEvent();
1409  }
1410 
1411  // Enable autopanning and cursor capture only when there is a sheet to be placed
1412  getViewControls()->SetAutoPan( sheet != nullptr );
1413  getViewControls()->CaptureCursor( sheet != nullptr );
1414  }
1415 
1416  getViewControls()->SetAutoPan( false );
1417  getViewControls()->CaptureCursor( false );
1419 
1420  return 0;
1421 }
1422 
1423 
1425 {
1426  wxPoint pos = aSheet->GetPosition();
1427  wxPoint size = (wxPoint) aPos - pos;
1428 
1429  size.x = std::max( size.x, MIN_SHEET_WIDTH );
1430  size.y = std::max( size.y, MIN_SHEET_HEIGHT );
1431 
1432  wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
1433  aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
1434 }
1435 
1436 
1438 {
1452 }
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
bool IsBold() const
Definition: eda_text.h:183
static TOOL_ACTION properties
Definition: ee_actions.h:117
bool SchematicCleanUp(SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:163
PINSHEETLABEL_SHAPE m_lastGlobalLabelShape
int TwoClickPlace(const TOOL_EVENT &aEvent)
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
static TOOL_ACTION finishSheet
Definition: ee_actions.h:94
bool Init() override
Init() is called once upon a registration of the tool.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void SetPosition(const wxPoint &aPosition) override
Definition: sch_symbol.h:642
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
static TOOL_ACTION activatePointEditor
Definition: actions.h:168
SCH_SHEET_PIN * createSheetPin(SCH_SHEET *aSheet, SCH_HIERLABEL *aLabel)
wxPoint GetStartPoint() const
Definition: sch_line.h:90
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:331
Holds all the data relating to one schematic.
Definition: schematic.h:59
#define IS_NEW
New item, just created.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
#define IS_RESIZING
Item being resized.
This file is part of the common library.
static TOOL_ACTION doDelete
Definition: actions.h:72
virtual void SetPosition(const wxPoint &aPos)
Definition: eda_item.h:253
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:370
void AddToPreview(EDA_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1562
EDA_RECT GetCanvasFreeAreaPixels()
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:79
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:167
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:84
void SetItalic(bool isItalic)
Definition: eda_text.h:179
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
static TOOL_ACTION placeJunction
Definition: ee_actions.h:80
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1395
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:156
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:97
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:153
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
bool m_lastTextItalic
Re-entrancy guards.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
Schematic editor (Eeschema) main window.
static TOOL_ACTION placeBusWireEntry
Definition: ee_actions.h:81
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void SelectUnit(SCH_SYMBOL *aSymbol, int aUnit)
Definition: getpart.cpp:198
static const KICAD_T SheetsOnly[]
Definition: ee_collectors.h:46
static TOOL_ACTION mirrorH
Definition: ee_actions.h:116
wxPoint GetNearestGridPosition(const wxPoint &aPosition) const
Return the nearest aGridSize location to aPosition.
static TOOL_ACTION importSingleSheetPin
Definition: ee_actions.h:184
void sizeSheet(SCH_SHEET *aSheet, const VECTOR2I &aPos)
Set up handlers for various events.
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:159
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
Define a library symbol object.
Definition: lib_symbol.h:96
int PlaceImage(const TOOL_EVENT &aEvent)
PANEL_SYM_CHOOSER m_SymChooserPanel
std::vector< PICKED_SYMBOL > m_symbolHistoryList
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).
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:547
void SetPageNumber(const SCH_SHEET_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1129
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:204
#define MIN_SHEET_WIDTH
Definition: sch_sheet.h:37
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:83
static TOOL_ACTION mirrorV
Definition: ee_actions.h:115
static TOOL_ACTION rotateCW
Definition: ee_actions.h:113
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
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
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:181
void SetBorderWidth(int aWidth)
Definition: sch_sheet.h:109
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:42
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:66
bool IsItalic() const
Definition: eda_text.h:180
EE_SELECTION & GetSelection()
Return the set of currently selected items.
EESCHEMA_SETTINGS * eeconfig() const
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:88
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
static TOOL_ACTION drawSheet
Definition: ee_actions.h:85
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
Definition: sch_item.h:449
virtual void WarpCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:114
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: infobar.cpp:175
int PlaceSymbol(const TOOL_EVENT &aEvent)
AUTOPLACE_FIELDS m_AutoplaceFields
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:115
static TOOL_ACTION placePower
Definition: ee_actions.h:75
#define IS_MOVING
Item being moved.
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:78
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
virtual void PopTool(const std::string &actionName)
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
PICKED_SYMBOL PickSymbolFromLibTree(const SCHLIB_FILTER *aFilter, std::vector< PICKED_SYMBOL > &aHistoryList, bool aUseLibBrowser, int aUnit, int aConvert, bool aShowFootprints, const LIB_ID *aHighlight=nullptr, bool aAllowFields=true)
Call the library viewer to select symbol to import into schematic.
Definition: getpart.cpp:88
int ShowQuasiModal()
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Automatically orient all the fields in the symbol.
int SingleClickPlace(const TOOL_EVENT &aEvent)
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:432
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:447
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:87
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 placeImage
Definition: ee_actions.h:89
void ClearPreview()
Definition: view.cpp:1540
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:340
SCHEMATIC & Schematic() const
void UpdateHierarchyNavigator(bool aForceUpdate=false)
Run the Hierarchy Navigator dialog.
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:112
Definition of file extensions used in Kicad.
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
Definition: view_controls.h:41
Definition for symbol library class.
An interface for classes handling user events controlling the view behavior such as zooming,...
#define _(s)
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:154
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:177
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
LABEL_SPIN_STYLE GetLabelSpinStyle() const
Definition: sch_text.h:159
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
static TOOL_ACTION importSheetPin
Definition: ee_actions.h:86
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:53
static TOOL_ACTION placeSymbol
Definition: ee_actions.h:74
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
float m_autoPanMargin
How fast is panning when in auto mode.
Definition: view_controls.h:76
static TOOL_ACTION addNeededJunctions
Definition: ee_actions.h:72
wxPoint GetPosition() const override
Definition: sch_sheet.h:380
bool m_autoPanEnabled
Flag for turning on autopanning.
Definition: view_controls.h:70
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:40
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:87
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
Definition: seg.h:40
std::vector< PICKED_SYMBOL > m_powerHistoryList
static TOOL_ACTION placeLabel
Definition: ee_actions.h:82
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:460
void SetPosition(const wxPoint &aPosition) override
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
PINSHEETLABEL_SHAPE
Definition: sch_text.h:95
SCH_SHEET & Root() const
Definition: schematic.h:92
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:150
void AddItemToScreenAndUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItem, bool aUndoAppend)
Add an item to the schematic and adds the changes to the undo/redo container.
Schematic symbol object.
Definition: sch_symbol.h:78
int AddItemToSel(const TOOL_EVENT &aEvent)
SCH_SCREEN * LastScreen()
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
bool SelectPoint(const VECTOR2I &aWhere, const KICAD_T *aFilterList=EE_COLLECTOR::AllItems, EDA_ITEM **aItem=nullptr, bool *aSelectionCancelledFlag=nullptr, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
This overload of SelectPoint will create an EE_COLLECTOR and collect hits at location aWhere before c...
SCH_HIERLABEL * importHierLabel(SCH_SHEET *aSheet)
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
void RollbackSchematicFromUndo()
Perform an undo of the last edit WITHOUT logging a corresponding redo.
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
void VetoContextMenuMouseWarp()
Disable mouse warping after the current context menu is closed.
Definition: tool_manager.h:422
SCH_TEXT * createNewText(const VECTOR2I &aPosition, int aType)
Get the next queued text item.
static TOOL_ACTION placeNoConnect
Definition: ee_actions.h:79
Handle the component boundary box.
Definition: eda_rect.h:42
const std::string KiCadSchematicFileExtension
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:38
These settings were stored in SCH_BASE_FRAME previously.
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:401
wxPoint Centre() const
Definition: eda_rect.h:55
bool IsReactivate() const
Definition: tool_event.h:252
Class for a wire to bus entry.
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:458
void Activate()
Run the tool.
WX_INFOBAR * GetInfoBar()
SCH_SHEET_PATH & GetCurrentSheet() const
PINSHEETLABEL_SHAPE m_lastSheetPinType
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:49
LABEL_SPIN_STYLE m_lastTextOrientation
LIB_SYMBOL * GetLibSymbol(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
bool HasPosition() const
Definition: tool_event.h:240
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:264
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:521
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
int GetUnit() const
Definition: sch_symbol.h:195
virtual void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:319
bool HasPin(const wxString &aName) const
Checks if the sheet already has a sheet pin named aName.
Definition: sch_sheet.cpp:327
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:83
void ClearEditFlags()
Definition: eda_item.h:172
LIB_ID LibId
Definition: sch_screen.h:82
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
void SetBold(bool aBold)
Definition: eda_text.h:182
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193
SCH_SHEET_LIST FindAllSheetsForScreen(const SCH_SCREEN *aScreen) const
Return a SCH_SHEET_LIST with a copy of all the SCH_SHEET_PATH using a particular screen.
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
bool NoPrintableChars(const wxString &aString)
Return true if the string is empty or contains only whitespace.
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
const VECTOR2D Position() const
Returns the point where dragging has started.
Definition: tool_event.h:263
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
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:144
int DrawSheet(const TOOL_EVENT &aEvent)
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
static TOOL_ACTION cursorClick
Definition: actions.h:123
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:1518
bool AddInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1087
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:161
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void Resize(const wxSize &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:809
wxPoint GetPosition() const override
wxPoint GetEndPoint() const
Definition: sch_line.h:93
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup