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 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_point_editor.h"
28 #include <ee_actions.h>
29 #include <sch_edit_frame.h>
30 #include <sch_view.h>
31 #include <class_draw_panel_gal.h>
32 #include <project.h>
33 #include <id.h>
34 #include <eeschema_id.h>
35 #include <confirm.h>
36 #include <view/view_controls.h>
37 #include <view/view.h>
38 #include <sch_component.h>
39 #include <sch_no_connect.h>
40 #include <sch_line.h>
41 #include <sch_junction.h>
42 #include <sch_bus_entry.h>
43 #include <sch_text.h>
44 #include <sch_sheet.h>
45 #include <sch_bitmap.h>
46 #include <class_library.h>
47 
48 
50  EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawing" )
51 {
52 }
53 
54 
56 {
58 
59  auto belowRootSheetCondition = [] ( const SELECTION& aSel ) {
60  return g_CurrentSheet->Last() != g_RootSheet;
61  };
62 
63  auto& ctxMenu = m_menu.GetMenu();
64  ctxMenu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 2 );
65 
66  return true;
67 }
68 
69 
70 // History lists for PlaceComponent()
73 
74 
76 {
77  SCH_COMPONENT* component = aEvent.Parameter<SCH_COMPONENT*>();
78  SCHLIB_FILTER filter;
79  SCH_BASE_FRAME::HISTORY_LIST* historyList = nullptr;
80 
81  if( aEvent.IsAction( &EE_ACTIONS::placeSymbol ) )
82  historyList = &s_SymbolHistoryList;
83  else if (aEvent.IsAction( &EE_ACTIONS::placePower ) )
84  {
85  historyList = &s_PowerHistoryList;
86  filter.FilterPowerParts( true );
87  }
88  else
89  wxFAIL_MSG( "PlaceCompontent(): unexpected request" );
90 
91  getViewControls()->ShowCursor( true );
92 
93  // If a component was passed in get it ready for placement.
94  if( component )
95  {
96  component->SetFlags( IS_NEW | IS_MOVED );
97 
99  m_selectionTool->AddItemToSel( component );
100  }
101 
102  std::string tool = aEvent.GetCommandStr().get();
103  m_frame->PushTool( tool );
104  Activate();
105 
106  // Prime the pump
107  if( component )
108  {
109  getViewControls()->WarpCursor( getViewControls()->GetMousePosition( false ) );
111  }
112  else if( aEvent.HasPosition() )
114 
115  // Main loop: keep receiving events
116  while( TOOL_EVENT* evt = Wait() )
117  {
118  m_frame->GetCanvas()->SetCurrentCursor( component ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
119  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
120 
121  auto cleanup = [&] () {
123  m_view->ClearPreview();
124  delete component;
125  component = nullptr;
126  };
127 
128  if( evt->IsCancelInteractive() )
129  {
130  if( component )
131  cleanup();
132  else
133  {
134  m_frame->PopTool( tool );
135  break;
136  }
137  }
138  else if( evt->IsActivate() )
139  {
140  if( component )
141  cleanup();
142 
143  if( evt->IsMoveTool() )
144  {
145  // leave ourselves on the stack so we come back after the move
146  break;
147  }
148  else
149  {
150  m_frame->PopTool( tool );
151  break;
152  }
153  }
154  else if( evt->IsClick( BUT_LEFT ) )
155  {
156  if( !component )
157  {
159 
160  // Pick the module to be placed
161  auto sel = m_frame->SelectCompFromLibTree( &filter, *historyList, true, 1, 1,
163 
164  // Restore cursor after dialog
165  getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
166 
167  LIB_PART* part = sel.LibId.IsValid() ? m_frame->GetLibPart( sel.LibId ) : nullptr;
168 
169  if( !part )
170  continue;
171 
172  component = new SCH_COMPONENT( *part, g_CurrentSheet, sel, (wxPoint) cursorPos );
173  component->SetFlags( IS_NEW | IS_MOVED );
174 
175  // Be sure the link to the corresponding LIB_PART is OK:
176  component->Resolve( *m_frame->Prj().SchSymbolLibTable() );
177 
178  if( m_frame->GetAutoplaceFields() )
179  component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
180 
181  m_frame->SaveCopyForRepeatItem( component );
182 
183  m_view->ClearPreview();
184  m_view->AddToPreview( component->Clone() );
185  m_selectionTool->AddItemToSel( component );
186  }
187  else
188  {
189  SCH_COMPONENT* next_comp = nullptr;
190 
191  m_view->ClearPreview();
192  m_frame->AddItemToScreenAndUndoList( component );
193 
195  {
196  int new_unit = component->GetUnit();
197 
198  if( m_frame->GetUseAllUnits()
199  && component->GetUnit() < component->GetUnitCount() )
200  new_unit++;
201  else
202  new_unit = 1;
203 
204  // We are either stepping to the next unit or next component
205  if( m_frame->GetRepeatComponent() || new_unit > 1 )
206  {
207  next_comp = static_cast<SCH_COMPONENT*>( component->Duplicate() );
208  next_comp->SetFlags( IS_NEW | IS_MOVED );
209  next_comp->SetUnit( new_unit );
210  next_comp->SetUnitSelection( g_CurrentSheet, new_unit );
211  next_comp->SetTimeStamp( GetNewTimeStamp() );
212 
213  if( m_frame->GetAutoplaceFields() )
214  component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
215 
216  m_frame->SaveCopyForRepeatItem( next_comp );
217  m_view->AddToPreview( next_comp->Clone() );
218  m_selectionTool->AddItemToSel( next_comp );
219  }
220  }
221 
222  component = next_comp;
223  }
224  }
225  else if( evt->IsClick( BUT_RIGHT ) )
226  {
227  // Warp after context menu only if dragging...
228  if( !component )
230 
232  }
233  else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
234  {
235  if( evt->GetCommandId().get() >= ID_POPUP_SCH_SELECT_UNIT_CMP
236  && evt->GetCommandId().get() <= ID_POPUP_SCH_SELECT_UNIT_CMP_MAX )
237  {
238  int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
239 
240  if( component )
241  {
242  m_frame->SelectUnit( component, unit );
244  }
245  }
246  }
247  else if( component && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
248  {
249  component->SetPosition( (wxPoint)cursorPos );
250  m_view->ClearPreview();
251  m_view->AddToPreview( component->Clone() );
252  }
253  else
254  evt->SetPassEvent();
255 
256  // Enable autopanning and cursor capture only when there is a module to be placed
257  getViewControls()->SetAutoPan( component != nullptr );
258  getViewControls()->CaptureCursor( component != nullptr );
259  }
260 
261  return 0;
262 }
263 
264 
266 {
267  SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>();
268  bool immediateMode = image;
269  VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
270 
272  getViewControls()->ShowCursor( true );
273 
274  // Add all the drawable parts to preview
275  if( image )
276  {
277  image->SetPosition( (wxPoint)cursorPos );
278  m_view->ClearPreview();
279  m_view->AddToPreview( image->Clone() );
280  }
281 
282  std::string tool = aEvent.GetCommandStr().get();
283  m_frame->PushTool( tool );
284  Activate();
285 
286  // Prime the pump
287  if( image )
289  else if( aEvent.HasPosition() )
291 
292  // Main loop: keep receiving events
293  while( TOOL_EVENT* evt = Wait() )
294  {
295  m_frame->GetCanvas()->SetCurrentCursor( image ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
296  cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
297 
298  auto cleanup = [&] () {
300  m_view->ClearPreview();
301  delete image;
302  image = nullptr;
303  };
304 
305  if( evt->IsCancelInteractive() )
306  {
307  if( image )
308  cleanup();
309  else
310  {
311  m_frame->PopTool( tool );
312  break;
313  }
314 
315  if( immediateMode )
316  {
317  m_frame->PopTool( tool );
318  break;
319  }
320  }
321  else if( evt->IsActivate() )
322  {
323  if( image )
324  cleanup();
325 
326  if( evt->IsMoveTool() )
327  {
328  // leave ourselves on the stack so we come back after the move
329  break;
330  }
331  else
332  {
333  m_frame->PopTool( tool );
334  break;
335  }
336  }
337  else if( evt->IsClick( BUT_LEFT ) )
338  {
339  if( !image )
340  {
342  wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
343  _( "Image Files " ) + wxImage::GetImageExtWildcard(), wxFD_OPEN );
344 
345  if( dlg.ShowModal() != wxID_OK )
346  continue;
347 
348  // Restore cursor after dialog
349  getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
350 
351  wxString fullFilename = dlg.GetPath();
352 
353  if( wxFileExists( fullFilename ) )
354  image = new SCH_BITMAP( (wxPoint)cursorPos );
355 
356  if( !image || !image->ReadImageFile( fullFilename ) )
357  {
358  wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
359  delete image;
360  image = nullptr;
361  continue;
362  }
363 
364  image->SetFlags( IS_NEW | IS_MOVED );
365 
366  m_frame->SaveCopyForRepeatItem( image );
367 
368  m_view->ClearPreview();
369  m_view->AddToPreview( image->Clone() );
370  m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
371 
372  m_selectionTool->AddItemToSel( image );
373 
374  getViewControls()->SetCursorPosition( cursorPos, false );
375  }
376  else
377  {
379  image = nullptr;
381 
382  m_view->ClearPreview();
383 
384  if( immediateMode )
385  {
386  m_frame->PopTool( tool );
387  break;
388  }
389  }
390  }
391  else if( evt->IsClick( BUT_RIGHT ) )
392  {
393  // Warp after context menu only if dragging...
394  if( !image )
396 
398  }
399  else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
400  {
401  image->SetPosition( (wxPoint)cursorPos );
402  m_view->ClearPreview();
403  m_view->AddToPreview( image->Clone() );
404  m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
405  }
406  else
407  evt->SetPassEvent();
408 
409  // Enable autopanning and cursor capture only when there is a module to be placed
410  getViewControls()->SetAutoPan( image != nullptr );
411  getViewControls()->CaptureCursor( image != nullptr );
412  }
413 
414  return 0;
415 }
416 
417 
419 {
420  wxPoint cursorPos;
421  KICAD_T type = aEvent.Parameter<KICAD_T>();
422 
423  auto itemFactory = [&] () -> SCH_ITEM* {
424  switch( type )
425  {
426  case SCH_NO_CONNECT_T:
427  return new SCH_NO_CONNECT( cursorPos );
428  case SCH_JUNCTION_T:
429  return new SCH_JUNCTION( cursorPos );
431  return new SCH_BUS_WIRE_ENTRY( cursorPos, g_lastBusEntryShape );
432  case SCH_BUS_BUS_ENTRY_T:
433  return new SCH_BUS_BUS_ENTRY( cursorPos, g_lastBusEntryShape );
434  default:
435  return nullptr;
436  }
437  };
438 
439  if( type == SCH_JUNCTION_T && aEvent.HasPosition() )
440  {
441  EE_SELECTION& selection = m_selectionTool->GetSelection();
442  SCH_LINE* wire = dynamic_cast<SCH_LINE*>( selection.Front() );
443 
444  if( wire )
445  {
446  SEG seg( wire->GetStartPoint(), wire->GetEndPoint() );
447  VECTOR2I nearest = seg.NearestPoint( getViewControls()->GetCursorPosition() );
448  getViewControls()->SetCrossHairCursorPosition( nearest, false );
449  getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
450  }
451  }
452 
453  if( aEvent.IsAction( &EE_ACTIONS::placeSheetPin ) )
454  type = SCH_SHEET_PIN_T;
455 
457  getViewControls()->ShowCursor( true );
458  getViewControls()->SetSnapping( true );
459 
460  SCH_ITEM* previewItem = itemFactory();
461  m_view->ClearPreview();
462  m_view->AddToPreview( previewItem->Clone() );
463 
464  std::string tool = aEvent.GetCommandStr().get();
465  m_frame->PushTool( tool );
466  Activate();
467 
468  // Prime the pump
469  if( aEvent.HasPosition() )
471 
472  // Main loop: keep receiving events
473  while( TOOL_EVENT* evt = Wait() )
474  {
475  m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
476  cursorPos = (wxPoint) getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
477 
478  if( evt->IsCancelInteractive() )
479  {
480  m_frame->PopTool( tool );
481  break;
482  }
483  else if( evt->IsActivate() )
484  {
485  if( evt->IsMoveTool() )
486  {
487  // leave ourselves on the stack so we come back after the move
488  break;
489  }
490  else
491  {
492  m_frame->PopTool( tool );
493  break;
494  }
495  }
496  else if( evt->IsClick( BUT_LEFT ) )
497  {
498  if( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) )
499  {
500  if( type == SCH_JUNCTION_T )
501  m_frame->AddJunction( cursorPos );
502  else
503  {
504  SCH_ITEM* newItem = itemFactory();
505  newItem->SetFlags( IS_NEW );
506 
508  m_frame->SaveCopyForRepeatItem( newItem );
509 
512  m_frame->OnModify();
513  }
514  }
515  }
516  else if( evt->IsClick( BUT_RIGHT ) )
517  {
519  }
520  else if( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() )
521  {
522  previewItem->SetPosition( (wxPoint)cursorPos );
523  m_view->ClearPreview();
524  m_view->AddToPreview( previewItem->Clone() );
525  }
526  else if( evt->Category() == TC_COMMAND )
527  {
528  if( ( type == SCH_BUS_BUS_ENTRY_T || type == SCH_BUS_WIRE_ENTRY_T )
529  && ( evt->IsAction( &EE_ACTIONS::rotateCW )
530  || evt->IsAction( &EE_ACTIONS::rotateCCW )
531  || evt->IsAction( &EE_ACTIONS::mirrorX )
532  || evt->IsAction( &EE_ACTIONS::mirrorY )
533  || evt->IsAction( &EE_ACTIONS::toShapeBackslash )
534  || evt->IsAction( &EE_ACTIONS::toShapeSlash ) ) )
535  {
536  char shape;
537 
538  if( evt->IsAction( &EE_ACTIONS::toShapeSlash ) )
539  shape = '/';
540  else if( evt->IsAction( &EE_ACTIONS::toShapeBackslash ) )
541  shape = '\\';
542  else // everything else just flips the shape
543  shape = g_lastBusEntryShape == '/' ? '\\' : '/';
544 
545  if( previewItem )
546  {
547  static_cast<SCH_BUS_ENTRY_BASE*>( previewItem )->SetBusEntryShape( shape );
548  m_view->ClearPreview();
549  m_view->AddToPreview( previewItem->Clone() );
550  }
551 
552  g_lastBusEntryShape = shape;
553  }
554  }
555  else
556  evt->SetPassEvent();
557  }
558 
559  delete previewItem;
560  m_view->ClearPreview();
561 
562  return 0;
563 }
564 
565 
567 {
568  EDA_ITEM* item = nullptr;
569  bool importMode = aEvent.IsAction( &EE_ACTIONS::importSheetPin );
570  KICAD_T type = aEvent.Parameter<KICAD_T>();
571 
573  getViewControls()->ShowCursor( true );
574 
575  std::string tool = aEvent.GetCommandStr().get();
576  m_frame->PushTool( tool );
577  Activate();
578 
579  // Prime the pump
580  if( aEvent.HasPosition() )
582 
583  // Main loop: keep receiving events
584  while( TOOL_EVENT* evt = Wait() )
585  {
586  m_frame->GetCanvas()->SetCurrentCursor( item ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
587  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
588 
589  auto cleanup = [&] () {
591  m_view->ClearPreview();
592  delete item;
593  item = nullptr;
594  };
595 
596  if( evt->IsCancelInteractive() )
597  {
598  if( item )
599  cleanup();
600  else
601  {
602  m_frame->PopTool( tool );
603  break;
604  }
605  }
606  else if( evt->IsActivate() )
607  {
608  if( item )
609  cleanup();
610 
611  if( evt->IsPointEditor() )
612  {
613  // don't exit (the point editor runs in the background)
614  }
615  else if( evt->IsMoveTool() )
616  {
617  // leave ourselves on the stack so we come back after the move
618  break;
619  }
620  else
621  {
622  m_frame->PopTool( tool );
623  break;
624  }
625  }
626  else if( evt->IsClick( BUT_LEFT ) )
627  {
628  // First click creates...
629  if( !item )
630  {
632 
633  switch( type )
634  {
635  case SCH_LABEL_T:
637  break;
638  case SCH_HIER_LABEL_T:
640  break;
641  case SCH_GLOBAL_LABEL_T:
643  break;
644  case SCH_TEXT_T:
645  item = m_frame->CreateNewText( LAYER_NOTES );
646  break;
647  case SCH_SHEET_PIN_T:
648  {
649  SCH_HIERLABEL* label = nullptr;
650  SCH_SHEET* sheet = (SCH_SHEET*) m_selectionTool->SelectPoint( cursorPos,
652  if( !sheet )
653  {
654  m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
655  m_statusPopup->SetText( _( "Click over a sheet." ) );
656  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
657  m_statusPopup->PopupFor( 2000 );
658  break;
659  }
660 
661  if( importMode )
662  {
663  label = m_frame->ImportHierLabel( sheet );
664 
665  if( !label )
666  {
667  m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
668  m_statusPopup->SetText( _( "No new hierarchical labels found." ) );
669  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
670  m_statusPopup->PopupFor( 2000 );
671  break;
672  }
673  }
674 
675  item = m_frame->CreateSheetPin( sheet, label );
676  break;
677  }
678  default:
679  break;
680  }
681 
682  // Restore cursor after dialog
683  getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
684 
685  if( item )
686  {
687  item->SetFlags( IS_NEW | IS_MOVED );
688  m_view->ClearPreview();
689  m_view->AddToPreview( item->Clone() );
690  m_selectionTool->AddItemToSel( item );
691  }
692 
693  getViewControls()->SetCursorPosition( cursorPos, false );
694  }
695 
696  // ... and second click places:
697  else
698  {
699  item->ClearFlags( IS_MOVED );
701  item = m_frame->GetNextNewText();
702 
703  if( item )
704  {
706  item->SetFlags( IS_NEW | IS_MOVED );
707  m_view->ClearPreview();
708  m_view->AddToPreview( item->Clone() );
709  m_selectionTool->AddItemToSel( item );
710  }
711  else
712  {
713  m_view->ClearPreview();
714  }
715  }
716  }
717  else if( evt->IsClick( BUT_RIGHT ) )
718  {
719  // Warp after context menu only if dragging...
720  if( !item )
722 
724  }
725  else if( item && evt->IsSelectionEvent() )
726  {
727  // This happens if our text was replaced out from under us by ConvertTextType()
728  EE_SELECTION& selection = m_selectionTool->GetSelection();
729 
730  if( selection.GetSize() == 1 )
731  {
732  item = (SCH_ITEM*) selection.Front();
733  m_view->ClearPreview();
734  m_view->AddToPreview( item->Clone() );
735  }
736  else
737  item = nullptr;
738  }
739  else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
740  {
741  static_cast<SCH_ITEM*>( item )->SetPosition( (wxPoint) cursorPos );
742  m_view->ClearPreview();
743  m_view->AddToPreview( item->Clone() );
744  }
745  else
746  evt->SetPassEvent();
747 
748  // Enable autopanning and cursor capture only when there is a module to be placed
749  getViewControls()->SetAutoPan( item != nullptr );
750  getViewControls()->CaptureCursor( item != nullptr );
751  }
752 
753  return 0;
754 }
755 
756 
758 {
760  SCH_SHEET* sheet = nullptr;
761 
763  getViewControls()->ShowCursor( true );
764 
765  std::string tool = aEvent.GetCommandStr().get();
766  m_frame->PushTool( tool );
767  Activate();
768 
769  // Prime the pump
770  if( aEvent.HasPosition() )
772 
773  // Main loop: keep receiving events
774  while( TOOL_EVENT* evt = Wait() )
775  {
776  if( !pointEditor->HasPoint() )
777  m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
778 
779  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
780 
781  auto cleanup = [&] () {
783  m_view->ClearPreview();
784  delete sheet;
785  sheet = nullptr;
786  };
787 
788  if( evt->IsCancelInteractive() )
789  {
790  if( sheet )
791  cleanup();
792  else
793  {
794  m_frame->PopTool( tool );
795  break;
796  }
797  }
798  else if( evt->IsActivate() )
799  {
800  if( sheet )
801  cleanup();
802 
803  if( evt->IsPointEditor() )
804  {
805  // don't exit (the point editor runs in the background)
806  }
807  else if( evt->IsMoveTool() )
808  {
809  // leave ourselves on the stack so we come back after the move
810  break;
811  }
812  else
813  {
814  m_frame->PopTool( tool );
815  break;
816  }
817  }
818 
819  else if( evt->IsClick( BUT_LEFT ) && !sheet )
820  {
822 
823  sheet = new SCH_SHEET( (wxPoint) cursorPos );
824  sheet->SetFlags( IS_NEW | IS_RESIZED );
825  sheet->SetTimeStamp( GetNewTimeStamp() );
826  sheet->SetParent( m_frame->GetScreen() );
827  sheet->SetScreen( NULL );
828  sizeSheet( sheet, cursorPos );
829 
830  m_view->ClearPreview();
831  m_view->AddToPreview( sheet->Clone() );
832  }
833 
834  else if( sheet && ( evt->IsClick( BUT_LEFT )
835  || evt->IsAction( &EE_ACTIONS::finishSheet ) ) )
836  {
837  m_view->ClearPreview();
838  getViewControls()->SetAutoPan( false );
839  getViewControls()->CaptureCursor( false );
840 
841  if( m_frame->EditSheet( (SCH_SHEET*)sheet, g_CurrentSheet, nullptr ) )
842  {
844  m_selectionTool->AddItemToSel( sheet );
845  }
846  else
847  {
848  delete sheet;
849  }
850 
851  sheet = nullptr;
852  }
853 
854  else if( sheet && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
855  {
856  sizeSheet( sheet, cursorPos );
857  m_view->ClearPreview();
858  m_view->AddToPreview( sheet->Clone() );
859  }
860 
861  else if( evt->IsClick( BUT_RIGHT ) )
862  {
863  // Warp after context menu only if dragging...
864  if( !sheet )
866 
868  }
869  else
870  evt->SetPassEvent();
871 
872  // Enable autopanning and cursor capture only when there is a sheet to be placed
873  getViewControls()->SetAutoPan( sheet != nullptr );
874  getViewControls()->CaptureCursor( sheet != nullptr );
875  }
876 
877  return 0;
878 }
879 
880 
882 {
883  wxPoint pos = aSheet->GetPosition();
884  wxPoint size = (wxPoint) aPos - pos;
885 
886  size.x = std::max( size.x, MIN_SHEET_WIDTH );
887  size.y = std::max( size.y, MIN_SHEET_HEIGHT );
888 
889  wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
890  aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
891 }
892 
893 
895 {
910 }
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
Class for a bus to bus entry.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Change the time stamp to aNewTimeStamp and updates the reference path.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
bool SchematicCleanUp(SCH_SCREEN *aScreen=nullptr)
Performs routine schematic cleaning including breaking wire and buses and deleting identical objects ...
int TwoClickPlace(const TOOL_EVENT &aEvent)
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
void AddToPreview(EDA_ITEM *aItem, bool aTakeOwnership=true)
Definition: sch_view.cpp:155
static TOOL_ACTION finishSheet
Definition: ee_actions.h:101
SCH_ITEM * Duplicate(bool doClone=false)
Routine to create a new copy of given item.
Definition: sch_item.cpp:75
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
int PlaceComponent(const TOOL_EVENT &aEvent)
SCH_TEXT * CreateNewText(int aType)
Definition: edit_label.cpp:62
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
static TOOL_ACTION activatePointEditor
Definition: actions.h:159
wxPoint GetStartPoint() const
Definition: sch_line.h:95
SCH_SHEET * Last() const
Function Last returns a pointer to the last sheet of the list One can see the others sheet as the "pa...
char g_lastBusEntryShape
This file is part of the common library.
static TOOL_ACTION toShapeBackslash
Definition: ee_actions.h:132
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
VIEW_CONTROLS class definition.
bool HasPoint()
Indicates the cursor is over an edit point.
bool Resolve(PART_LIBS *aLibs)
Assigns the current LIB_PART from aLibs which this symbol is based on.
Class STATUS_TEXT_POPUP.
Definition: status_popup.h:79
bool GetShowFootprintPreviews() const
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
static TOOL_ACTION mirrorY
Definition: ee_actions.h:121
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:90
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
static TOOL_ACTION placeJunction
Definition: ee_actions.h:85
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1402
int GetUnitCount() const
Return the number of units per package of the symbol.
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
std::vector< COMPONENT_SELECTION > HISTORY_LIST
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
static SCH_BASE_FRAME::HISTORY_LIST s_PowerHistoryList
Schematic editor (Eeschema) main window.
static TOOL_ACTION placeBusBusEntry
Definition: ee_actions.h:87
LIB_PART * GetLibPart(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
static TOOL_ACTION placeBusWireEntry
Definition: ee_actions.h:86
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void SetUnitSelection(SCH_SHEET_PATH *aSheet, int aUnitSelection)
static const KICAD_T SheetsOnly[]
Definition: ee_collectors.h:45
wxPoint GetNearestGridPosition(const wxPoint &aPosition) const
Return the nearest aGridSize location to aPosition.
bool GetAutoplaceFields() const
int PlaceImage(const TOOL_EVENT &aEvent)
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
bool EditSheet(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:518
const bool GetUseAllUnits()
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
#define MIN_SHEET_WIDTH
Definition: sch_sheet.h:42
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
static TOOL_ACTION rotateCW
Definition: ee_actions.h:118
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:177
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:69
EE_SELECTION & GetSelection()
Function GetSelection()
#define IS_NEW
New item, just created.
Definition: base_struct.h:120
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:91
timestamp_t GetNewTimeStamp()
Definition: common.cpp:217
virtual void WarpCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
Function WarpCursor() If enabled (.
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:119
int GetUnit() const
static TOOL_ACTION placePower
Definition: ee_actions.h:80
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:265
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
COMPONENT_SELECTION SelectCompFromLibTree(const SCHLIB_FILTER *aFilter, std::vector< COMPONENT_SELECTION > &aHistoryList, bool aUseLibBrowser, int aUnit, int aConvert, bool aShowFootprints, const LIB_ID *aHighlight=nullptr, bool aAllowFields=true)
Function SelectComponentFromLib Calls the library viewer to select component to import into schematic...
Definition: getpart.cpp:94
virtual void SetPosition(const wxPoint &aPosition)=0
Function SetPosition set the schematic item position to aPosition.
static TOOL_ACTION placeSheetPin
Definition: ee_actions.h:92
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area.
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
int SingleClickPlace(const TOOL_EVENT &aEvent)
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:94
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Class TOOL_EVENT.
Definition: tool_event.h:171
static TOOL_ACTION placeImage
Definition: ee_actions.h:96
void ClearPreview()
Definition: sch_view.cpp:143
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:234
Define a library symbol object.
void SaveCopyForRepeatItem(SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
SCH_JUNCTION * AddJunction(const wxPoint &aPos, bool aAppendToUndo=false, bool aFinal=true)
static TOOL_ACTION mirrorX
Definition: ee_actions.h:120
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:140
static TOOL_ACTION importSheetPin
Definition: ee_actions.h:93
void SetUnit(int aUnit)
Change the unit number to aUnit.
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:58
static TOOL_ACTION placeSymbol
Definition: ee_actions.h:79
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Moves the graphic crosshair cursor to the requested position expressed in world coordinates.
SCH_TEXT * GetNextNewText()
Gets the next queued text item.
Definition: edit_label.cpp:50
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_sheet.h:543
#define _(s)
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:42
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
void SelectUnit(SCH_COMPONENT *aComponent, int aUnit)
Definition: getpart.cpp:209
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:98
Definition: seg.h:36
static TOOL_ACTION placeLabel
Definition: ee_actions.h:88
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
const bool GetRepeatComponent()
SCH_HIERLABEL * ImportHierLabel(SCH_SHEET *aSheet)
Import a hierarchical label with no attached sheet pin.
Definition: sheet.cpp:815
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Automatically orient all the fields in the component.
int AddItemToSel(const TOOL_EVENT &aEvent)
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
#define max(a, b)
Definition: auxiliary.h:86
Class EE_POINT_EDITOR.
void VetoContextMenuMouseWarp()
Disables mouse warping after the current context menu is closed.
Definition: tool_manager.h:384
static TOOL_ACTION placeNoConnect
Definition: ee_actions.h:84
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: sch_bitmap.cpp:87
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:43
#define IS_RESIZED
Item being resized.
Definition: base_struct.h:121
virtual void PopTool(const std::string &actionName)
Class for a wire to bus entry.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:266
void Activate()
Function Activate() Runs the tool.
bool ReadImageFile(const wxString &aFullFilename)
Reads and stores an image file.
Definition: sch_bitmap.cpp:81
Class EE_TOOL_BASE.
Definition: ee_tool_base.h:50
bool HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition: tool_event.h:260
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
Definition for part library class.
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
EDA_ITEM * SelectPoint(const VECTOR2I &aWhere, const KICAD_T *aFilterList=EE_COLLECTOR::AllItems, bool *aSelectionCancelledFlag=NULL, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Function selectPoint() Selects an item pointed by the parameter aWhere.
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:89
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Definition: sch_item.h:114
Definitions of the SCH_TEXT class and derivatives for Eeschema.
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
SCH_SHEET_PIN * CreateSheetPin(SCH_SHEET *aSheet, SCH_HIERLABEL *aLabel)
Create a new SCH_SHEET_PIN object and add it to aSheet at the current cursor position.
Definition: sheet.cpp:779
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Definition: sch_bitmap.h:141
void setTransitions() override
Sets up handlers for various events.
static TOOL_ACTION toShapeSlash
Definition: ee_actions.h:131
static TOOL_ACTION refreshPreview
Definition: actions.h:101
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false)=0
Moves cursor to the requested position expressed in world coordinates.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:182
int DrawSheet(const TOOL_EVENT &aEvent)
static TOOL_ACTION cursorClick
Definition: actions.h:115
static SCH_BASE_FRAME::HISTORY_LIST s_SymbolHistoryList
void Resize(const wxSize &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:721
void sizeSheet(SCH_SHEET *aSheet, VECTOR2I aPos)
void AddItemToScreenAndUndoList(SCH_ITEM *aItem, bool aUndoAppend=false)
Add an item to the schematic and adds the changes to the undo/redo container.
#define IS_MOVED
Item being moved.
Definition: base_struct.h:119
wxPoint GetEndPoint() const
Definition: sch_line.h:98
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup