KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 CERN
5 * Copyright (C) 2019-2024 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_sheet_path.h"
26#include <memory>
27
28#include <kiplatform/ui.h>
29#include <optional>
30#include <project_sch.h>
37#include <ee_actions.h>
38#include <sch_edit_frame.h>
39#include <pgm_base.h>
40#include <eeschema_id.h>
41#include <confirm.h>
42#include <view/view_controls.h>
43#include <view/view.h>
44#include <sch_symbol.h>
45#include <sch_no_connect.h>
46#include <sch_line.h>
47#include <sch_junction.h>
48#include <sch_bus_entry.h>
49#include <sch_rule_area.h>
50#include <sch_text.h>
51#include <sch_textbox.h>
52#include <sch_table.h>
53#include <sch_tablecell.h>
54#include <sch_sheet.h>
55#include <sch_sheet_pin.h>
56#include <sch_label.h>
57#include <sch_bitmap.h>
58#include <schematic.h>
59#include <sch_commit.h>
60#include <scoped_set_reset.h>
61#include <symbol_library.h>
62#include <eeschema_settings.h>
64#include <dialogs/dialog_text_properties.h>
67#include <dialogs/dialog_table_properties.h>
70#include <string_utils.h>
72#include <wx/filedlg.h>
73#include <wx/msgdlg.h>
74
76 EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawing" ),
77 m_lastSheetPinType( LABEL_FLAG_SHAPE::L_INPUT ),
78 m_lastGlobalLabelShape( LABEL_FLAG_SHAPE::L_INPUT ),
79 m_lastNetClassFlagShape( LABEL_FLAG_SHAPE::F_ROUND ),
80 m_lastTextOrientation( SPIN_STYLE::RIGHT ),
81 m_lastTextBold( false ),
82 m_lastTextItalic( false ),
83 m_lastTextAngle( ANGLE_0 ),
84 m_lastTextboxAngle( ANGLE_0 ),
85 m_lastTextHJustify( GR_TEXT_H_ALIGN_CENTER ),
86 m_lastTextVJustify( GR_TEXT_V_ALIGN_CENTER ),
87 m_lastTextboxHJustify( GR_TEXT_H_ALIGN_LEFT ),
88 m_lastTextboxVJustify( GR_TEXT_V_ALIGN_TOP ),
89 m_lastFillStyle( FILL_T::NO_FILL ),
90 m_lastTextboxFillStyle( FILL_T::NO_FILL ),
91 m_lastFillColor( COLOR4D::UNSPECIFIED ),
92 m_lastTextboxFillColor( COLOR4D::UNSPECIFIED ),
93 m_lastStroke( 0, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
94 m_lastTextboxStroke( 0, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
95 m_mruPath( wxEmptyString ),
96 m_lastAutoLabelRotateOnPlacement( false ),
97 m_drawingRuleArea( false ),
98 m_inDrawingTool( false )
99{
100}
101
102
104{
106
107 auto belowRootSheetCondition =
108 [&]( const SELECTION& aSel )
109 {
110 return m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root();
111 };
112
113 auto inDrawingRuleArea =
114 [&]( const SELECTION& aSel )
115 {
116 return m_drawingRuleArea;
117 };
118
119 CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
120 ctxMenu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 150 );
121 ctxMenu.AddItem( EE_ACTIONS::closeOutline, inDrawingRuleArea, 200 );
122 ctxMenu.AddItem( EE_ACTIONS::deleteLastPoint, inDrawingRuleArea, 200 );
123
124 return true;
125}
126
127
129{
130 SCH_SYMBOL* symbol = aEvent.Parameter<SCH_SYMBOL*>();
132 std::vector<PICKED_SYMBOL>* historyList = nullptr;
133 bool ignorePrimePosition = false;
134 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
135 SCH_SCREEN* screen = m_frame->GetScreen();
136
137 if( m_inDrawingTool )
138 return 0;
139
141
144 VECTOR2I cursorPos;
145
146 // First we need to get all instances of this sheet so we can annotate
147 // whatever symbols we place on all copies
149 SCH_SHEET_LIST newInstances =
151 newInstances.SortByPageNumbers();
152
153 // Get a list of all references in the schematic to avoid duplicates wherever
154 // they're placed
155 SCH_REFERENCE_LIST existingRefs;
156 hierarchy.GetSymbols( existingRefs );
157 existingRefs.SortByReferenceOnly();
158
159 if( aEvent.IsAction( &EE_ACTIONS::placeSymbol ) )
160 {
161 historyList = &m_symbolHistoryList;
162 }
163 else if (aEvent.IsAction( &EE_ACTIONS::placePower ) )
164 {
165 historyList = &m_powerHistoryList;
166 filter.FilterPowerSymbols( true );
167 }
168 else
169 {
170 wxFAIL_MSG( "PlaceSymbol(): unexpected request" );
171 }
172
173 m_frame->PushTool( aEvent );
174
175 auto addSymbol =
176 [this]( SCH_SYMBOL* aSymbol )
177 {
179 m_selectionTool->AddItemToSel( aSymbol );
180
181 aSymbol->SetFlags( IS_NEW | IS_MOVING );
182
184 m_view->AddToPreview( aSymbol, false ); // Add, but not give ownership
185
186 // Set IS_MOVING again, as AddItemToCommitAndScreen() will have cleared it.
187 aSymbol->SetFlags( IS_MOVING );
189 };
190
191 auto setCursor =
192 [&]()
193 {
194 m_frame->GetCanvas()->SetCurrentCursor( symbol ? KICURSOR::MOVING
195 : KICURSOR::COMPONENT );
196 };
197
198 auto cleanup =
199 [&]()
200 {
203 delete symbol;
204 symbol = nullptr;
205
206 existingRefs.Clear();
207 hierarchy.GetSymbols( existingRefs );
208 existingRefs.SortByReferenceOnly();
209 };
210
211 auto annotate =
212 [&]()
213 {
215
216 // Then we need to annotate all instances by sheet
217 for( SCH_SHEET_PATH& instance : newInstances )
218 {
219 SCH_REFERENCE newReference( symbol, instance );
221 refs.AddItem( newReference );
222
223 if( cfg->m_AnnotatePanel.automatic || newReference.AlwaysAnnotate() )
224 {
228 existingRefs, false, &hierarchy );
229
230 refs.UpdateAnnotation();
231
232 // Update existing refs for next iteration
233 for( size_t i = 0; i < refs.GetCount(); i++ )
234 existingRefs.AddItem( refs[i] );
235 }
236 }
237
239 };
240
241 Activate();
242
243 // Must be done after Activate() so that it gets set into the correct context
244 getViewControls()->ShowCursor( true );
245
246 // Set initial cursor
247 setCursor();
248
249 // Prime the pump
250 if( symbol )
251 {
252 addSymbol( symbol );
253 annotate();
254 getViewControls()->WarpMouseCursor( getViewControls()->GetMousePosition( false ) );
255 }
256 else if( aEvent.HasPosition() )
257 {
258 m_toolMgr->PrimeTool( aEvent.Position() );
259 }
260 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
261 {
262 m_toolMgr->PrimeTool( { 0, 0 } );
263 ignorePrimePosition = true;
264 }
265
266 // Main loop: keep receiving events
267 while( TOOL_EVENT* evt = Wait() )
268 {
269 setCursor();
270 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
271 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
272
273 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_CONNECTABLE );
274 controls->ForceCursorPosition( true, cursorPos );
275
276 // The tool hotkey is interpreted as a click when drawing
277 bool isSyntheticClick = symbol && evt->IsActivate() && evt->HasPosition()
278 && evt->Matches( aEvent );
279
280 if( evt->IsCancelInteractive() || ( symbol && evt->IsAction( &ACTIONS::undo ) ) )
281 {
283
284 if( symbol )
285 {
286 cleanup();
287 }
288 else
289 {
290 m_frame->PopTool( aEvent );
291 break;
292 }
293 }
294 else if( evt->IsActivate() && !isSyntheticClick )
295 {
296 if( symbol && evt->IsMoveTool() )
297 {
298 // we're already moving our own item; ignore the move tool
299 evt->SetPassEvent( false );
300 continue;
301 }
302
303 if( symbol )
304 {
305 m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel symbol creation." ) );
306 evt->SetPassEvent( false );
307 continue;
308 }
309
310 if( evt->IsMoveTool() )
311 {
312 // leave ourselves on the stack so we come back after the move
313 break;
314 }
315 else
316 {
317 m_frame->PopTool( aEvent );
318 break;
319 }
320 }
321 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
322 {
323 if( !symbol )
324 {
326
329
330 auto compareByLibID =
331 []( const LIB_SYMBOL* aFirst, const LIB_SYMBOL* aSecond ) -> bool
332 {
333 return aFirst->GetLibId().Format() < aSecond->GetLibId().Format();
334 };
335
336 std::set<LIB_SYMBOL*, decltype( compareByLibID )> part_list( compareByLibID );
337
338 for( SCH_SHEET_PATH& sheet : hierarchy )
339 {
340 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
341 {
342 SCH_SYMBOL* s = static_cast<SCH_SYMBOL*>( item );
343 LIB_SYMBOL* libSymbol = SchGetLibSymbol( s->GetLibId(), libs, cache );
344
345 if( libSymbol )
346 part_list.insert( libSymbol );
347 }
348 }
349
350 std::vector<PICKED_SYMBOL> alreadyPlaced;
351
352 for( LIB_SYMBOL* libSymbol : part_list )
353 {
354 PICKED_SYMBOL pickedSymbol;
355 pickedSymbol.LibId = libSymbol->GetLibId();
356 alreadyPlaced.push_back( pickedSymbol );
357 }
358
359 // Pick the symbol to be placed
360 bool footprintPreviews = m_frame->eeconfig()->m_Appearance.footprint_preview;
361 PICKED_SYMBOL sel = m_frame->PickSymbolFromLibrary( &filter, *historyList,
362 alreadyPlaced,
363 footprintPreviews );
364
365 LIB_SYMBOL* libSymbol = sel.LibId.IsValid() ? m_frame->GetLibSymbol( sel.LibId )
366 : nullptr;
367
368 if( !libSymbol )
369 continue;
370
371 // If we started with a hotkey which has a position then warp back to that.
372 // Otherwise update to the current mouse position pinned inside the autoscroll
373 // boundaries.
374 if( evt->IsPrime() && !ignorePrimePosition )
375 {
376 cursorPos = grid.Align( evt->Position(), GRID_HELPER_GRIDS::GRID_CONNECTABLE );
377 getViewControls()->WarpMouseCursor( cursorPos, true );
378 }
379 else
380 {
382 cursorPos = grid.Align( getViewControls()->GetMousePosition(),
383 GRID_HELPER_GRIDS::GRID_CONNECTABLE );
384 }
385
386 symbol = new SCH_SYMBOL( *libSymbol, &m_frame->GetCurrentSheet(), sel, cursorPos,
387 &m_frame->Schematic() );
388 addSymbol( symbol );
389 annotate();
390
391 // Update the list of references for the next symbol placement.
392 SCH_REFERENCE placedSymbolReference( symbol, m_frame->GetCurrentSheet() );
393 existingRefs.AddItem( placedSymbolReference );
394 existingRefs.SortByReferenceOnly();
395
397 symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
398
399 // Update cursor now that we have a symbol
400 setCursor();
401 }
402 else
403 {
405 m_frame->AddToScreen( symbol, screen );
406
408 symbol->AutoplaceFields( screen, false /* aManual */ );
409
411
412 SCH_COMMIT commit( m_toolMgr );
413 commit.Added( symbol, screen );
414
416 lwbTool->TrimOverLappingWires( &commit, &m_selectionTool->GetSelection() );
417 lwbTool->AddJunctionsIfNeeded( &commit, &m_selectionTool->GetSelection() );
418
419 commit.Push( _( "Add Symbol" ) );
420
421 SCH_SYMBOL* nextSymbol = nullptr;
422
425 {
426 int new_unit = symbol->GetUnit();
427
429 && symbol->GetUnit() < symbol->GetUnitCount() )
430 {
431 new_unit++;
432 }
433 else
434 {
435 new_unit = 1;
436 }
437
438 // We are either stepping to the next unit or next symbol
439 if( m_frame->eeconfig()->m_SymChooserPanel.keep_symbol || new_unit > 1 )
440 {
441 nextSymbol = static_cast<SCH_SYMBOL*>( symbol->Duplicate() );
442 nextSymbol->SetUnit( new_unit );
443 nextSymbol->SetUnitSelection( new_unit );
444
445 // Start new annotation sequence at first unit
446 if( new_unit == 1 )
447 nextSymbol->ClearAnnotation( nullptr, false );
448
449 addSymbol( nextSymbol );
450 symbol = nextSymbol;
451 annotate();
452
453 // Update the list of references for the next symbol placement.
454 SCH_REFERENCE placedSymbolReference( symbol, m_frame->GetCurrentSheet() );
455 existingRefs.AddItem( placedSymbolReference );
456 existingRefs.SortByReferenceOnly();
457 }
458 }
459
460 symbol = nextSymbol;
461 }
462 }
463 else if( evt->IsClick( BUT_RIGHT ) )
464 {
465 // Warp after context menu only if dragging...
466 if( !symbol )
468
470 }
471 else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
472 {
473 if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT
474 && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_END )
475 {
476 int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT;
477
478 if( symbol )
479 {
480 m_frame->SelectUnit( symbol, unit );
482 }
483 }
484 else if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_BASE
485 && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_ALT )
486 {
487 int bodyStyle = ( *evt->GetCommandId() - ID_POPUP_SCH_SELECT_BASE ) + 1;
488
489 if( symbol && symbol->GetBodyStyle() != bodyStyle )
490 {
491 m_frame->FlipBodyStyle( symbol );
493 }
494 }
495 }
496 else if( evt->IsAction( &ACTIONS::duplicate )
497 || evt->IsAction( &EE_ACTIONS::repeatDrawItem ) )
498 {
499 if( symbol )
500 {
501 // This doesn't really make sense; we'll just end up dragging a stack of
502 // objects so we ignore the duplicate and just carry on.
503 wxBell();
504 continue;
505 }
506
507 // Exit. The duplicate will run in its own loop.
508 m_frame->PopTool( aEvent );
509 break;
510 }
511 else if( symbol && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
512 {
513 symbol->SetPosition( cursorPos );
515 m_view->AddToPreview( symbol, false ); // Add, but not give ownership
516 m_frame->SetMsgPanel( symbol );
517 }
518 else if( symbol && evt->IsAction( &ACTIONS::doDelete ) )
519 {
520 cleanup();
521 }
522 else if( symbol && evt->IsAction( &ACTIONS::redo ) )
523 {
524 wxBell();
525 }
526 else
527 {
528 evt->SetPassEvent();
529 }
530
531 // Enable autopanning and cursor capture only when there is a symbol to be placed
532 getViewControls()->SetAutoPan( symbol != nullptr );
533 getViewControls()->CaptureCursor( symbol != nullptr );
534 }
535
536 getViewControls()->SetAutoPan( false );
537 getViewControls()->CaptureCursor( false );
538 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
539
540 return 0;
541}
542
543
545{
546 SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>();
547 bool immediateMode = image != nullptr;
548 bool ignorePrimePosition = false;
549 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
550
551 if( m_inDrawingTool )
552 return 0;
553
555
558 VECTOR2I cursorPos;
559
561
562 // Add all the drawable symbols to preview
563 if( image )
564 {
565 image->SetPosition( getViewControls()->GetCursorPosition() );
567 m_view->AddToPreview( image, false ); // Add, but not give ownership
568 }
569
570 m_frame->PushTool( aEvent );
571
572 auto setCursor =
573 [&]()
574 {
575 if( image )
576 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
577 else
578 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
579 };
580
581 auto cleanup =
582 [&] ()
583 {
587 delete image;
588 image = nullptr;
589 };
590
591 Activate();
592
593 // Must be done after Activate() so that it gets set into the correct context
594 getViewControls()->ShowCursor( true );
595
596 // Set initial cursor
597 setCursor();
598
599 // Prime the pump
600 if( image )
601 {
603 }
604 else if( aEvent.HasPosition() )
605 {
606 m_toolMgr->PrimeTool( aEvent.Position() );
607 }
608 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
609 {
610 m_toolMgr->PrimeTool( { 0, 0 } );
611 ignorePrimePosition = true;
612 }
613
614 // Main loop: keep receiving events
615 while( TOOL_EVENT* evt = Wait() )
616 {
617 setCursor();
618 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
619 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
620
621 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
622 controls->ForceCursorPosition( true, cursorPos );
623
624 // The tool hotkey is interpreted as a click when drawing
625 bool isSyntheticClick = image && evt->IsActivate() && evt->HasPosition()
626 && evt->Matches( aEvent );
627
628 if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
629 {
631
632 if( image )
633 {
634 cleanup();
635 }
636 else
637 {
638 m_frame->PopTool( aEvent );
639 break;
640 }
641
642 if( immediateMode )
643 {
644 m_frame->PopTool( aEvent );
645 break;
646 }
647 }
648 else if( evt->IsActivate() && !isSyntheticClick )
649 {
650 if( image && evt->IsMoveTool() )
651 {
652 // we're already moving our own item; ignore the move tool
653 evt->SetPassEvent( false );
654 continue;
655 }
656
657 if( image )
658 {
659 m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel image creation." ) );
660 evt->SetPassEvent( false );
661 continue;
662 }
663
664 if( evt->IsMoveTool() )
665 {
666 // leave ourselves on the stack so we come back after the move
667 break;
668 }
669 else
670 {
671 m_frame->PopTool( aEvent );
672 break;
673 }
674 }
675 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
676 {
677 if( !image )
678 {
680
681 wxFileDialog dlg( m_frame, _( "Choose Image" ), m_mruPath, wxEmptyString,
682 _( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(),
683 wxFD_OPEN );
684
685 if( dlg.ShowModal() != wxID_OK )
686 continue;
687
688 // If we started with a hotkey which has a position then warp back to that.
689 // Otherwise update to the current mouse position pinned inside the autoscroll
690 // boundaries.
691 if( evt->IsPrime() && !ignorePrimePosition )
692 {
693 cursorPos = grid.Align( evt->Position() );
694 getViewControls()->WarpMouseCursor( cursorPos, true );
695 }
696 else
697 {
699 cursorPos = getViewControls()->GetMousePosition();
700 }
701
702 wxString fullFilename = dlg.GetPath();
703 m_mruPath = wxPathOnly( fullFilename );
704
705 if( wxFileExists( fullFilename ) )
706 image = new SCH_BITMAP( cursorPos );
707
708 if( !image || !image->ReadImageFile( fullFilename ) )
709 {
710 wxMessageBox( _( "Could not load image from '%s'." ), fullFilename );
711 delete image;
712 image = nullptr;
713 continue;
714 }
715
716 image->SetFlags( IS_NEW | IS_MOVING );
717
719
721 m_view->AddToPreview( image, false ); // Add, but not give ownership
722 m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
723
725
726 getViewControls()->SetCursorPosition( cursorPos, false );
727 setCursor();
728 }
729 else
730 {
731 SCH_COMMIT commit( m_toolMgr );
732 commit.Add( image, m_frame->GetScreen() );
733 commit.Push( _( "Add Image" ) );
734
735 image = nullptr;
737
739
740 if( immediateMode )
741 {
742 m_frame->PopTool( aEvent );
743 break;
744 }
745 }
746 }
747 else if( evt->IsClick( BUT_RIGHT ) )
748 {
749 // Warp after context menu only if dragging...
750 if( !image )
752
754 }
755 else if( evt->IsAction( &ACTIONS::duplicate )
756 || evt->IsAction( &EE_ACTIONS::repeatDrawItem ) )
757 {
758 if( image )
759 {
760 // This doesn't really make sense; we'll just end up dragging a stack of
761 // objects so we ignore the duplicate and just carry on.
762 wxBell();
763 continue;
764 }
765
766 // Exit. The duplicate will run in its own loop.
767 m_frame->PopTool( aEvent );
768 break;
769 }
770 else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
771 {
772 image->SetPosition( cursorPos );
774 m_view->AddToPreview( image, false ); // Add, but not give ownership
775 m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
777 }
778 else if( image && evt->IsAction( &ACTIONS::doDelete ) )
779 {
780 cleanup();
781 }
782 else if( image && evt->IsAction( &ACTIONS::redo ) )
783 {
784 wxBell();
785 }
786 else
787 {
788 evt->SetPassEvent();
789 }
790
791 // Enable autopanning and cursor capture only when there is an image to be placed
792 getViewControls()->SetAutoPan( image != nullptr );
793 getViewControls()->CaptureCursor( image != nullptr );
794 }
795
796 getViewControls()->SetAutoPan( false );
797 getViewControls()->CaptureCursor( false );
798 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
799
800 return 0;
801}
802
803
805{
806 if( m_inDrawingTool )
807 return 0;
808
810
811 // Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint
812 // items if needed
814 int dlgResult = dlg.ShowModal();
815
816 std::list<std::unique_ptr<EDA_ITEM>>& list = dlg.GetImportedItems();
817
818 if( dlgResult != wxID_OK )
819 return 0;
820
821 // Ensure the list is not empty:
822 if( list.empty() )
823 {
824 wxMessageBox( _( "No graphic items found in file." ) );
825 return 0;
826 }
827
829
831 std::vector<SCH_ITEM*> newItems; // all new items, including group
832 std::vector<SCH_ITEM*> selectedItems; // the group, or newItems if no group
833 EE_SELECTION preview;
834 SCH_COMMIT commit( m_toolMgr );
835
836 for( std::unique_ptr<EDA_ITEM>& ptr : list )
837 {
838 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( ptr.get() );
839 wxCHECK2( item, continue );
840
841 newItems.push_back( item );
842 selectedItems.push_back( item );
843 preview.Add( item );
844
845 ptr.release();
846 }
847
848 if( !dlg.IsPlacementInteractive() )
849 {
850 // Place the imported drawings
851 for( SCH_ITEM* item : newItems )
852 commit.Add(item, m_frame->GetScreen());
853
854 commit.Push( _( "Import Graphic" ) );
855 return 0;
856 }
857
858 m_view->Add( &preview );
859
860 // Clear the current selection then select the drawings so that edit tools work on them
862
863 EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() );
865
866 m_frame->PushTool( aEvent );
867
868 auto setCursor = [&]()
869 {
870 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
871 };
872
873 Activate();
874 // Must be done after Activate() so that it gets set into the correct context
875 controls->ShowCursor( true );
876 controls->ForceCursorPosition( false );
877 // Set initial cursor
878 setCursor();
879
880 //SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );
882
883 // Now move the new items to the current cursor position:
884 VECTOR2I cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
885 VECTOR2I delta = cursorPos;
886 VECTOR2I currentOffset;
887
888 for( SCH_ITEM* item : selectedItems )
889 item->Move( delta );
890
891 currentOffset += delta;
892
893 m_view->Update( &preview );
894
895 // Main loop: keep receiving events
896 while( TOOL_EVENT* evt = Wait() )
897 {
898 setCursor();
899
900 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
901 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
902
903 cursorPos = grid.Align( controls->GetMousePosition(), GRID_GRAPHICS );
904 controls->ForceCursorPosition( true, cursorPos );
905
906 if( evt->IsCancelInteractive() || evt->IsActivate() )
907 {
909
910 for( SCH_ITEM* item : newItems )
911 delete item;
912
913 break;
914 }
915 else if( evt->IsMotion() )
916 {
917 delta = cursorPos - currentOffset;
918
919 for( SCH_ITEM* item : selectedItems )
920 item->Move( delta );
921
922 currentOffset += delta;
923
924 m_view->Update( &preview );
925 }
926 else if( evt->IsClick( BUT_RIGHT ) )
927 {
929 }
930 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
931 {
932 // Place the imported drawings
933 for( SCH_ITEM* item : newItems )
934 commit.Add( item, m_frame->GetScreen() );
935
936 commit.Push( _( "Import Graphic" ) );
937 break; // This is a one-shot command, not a tool
938 }
939 else
940 {
941 evt->SetPassEvent();
942 }
943 }
944
945 preview.Clear();
946 m_view->Remove( &preview );
947
948 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
949 controls->ForceCursorPosition( false );
950
951 m_frame->PopTool( aEvent );
952
953 return 0;
954}
955
956
958{
959 VECTOR2I cursorPos;
960 KICAD_T type = aEvent.Parameter<KICAD_T>();
963 SCH_ITEM* previewItem;
964 bool loggedInfoBarError = false;
965 wxString description;
966 SCH_SCREEN* screen = m_frame->GetScreen();
967 bool allowRepeat = false; // Set to true to allow new item repetition
968
969 if( m_inDrawingTool )
970 return 0;
971
973
974 if( type == SCH_JUNCTION_T && aEvent.HasPosition() )
975 {
977 SCH_LINE* wire = dynamic_cast<SCH_LINE*>( selection.Front() );
978
979 if( wire )
980 {
981 SEG seg( wire->GetStartPoint(), wire->GetEndPoint() );
982 VECTOR2I nearest = seg.NearestPoint( getViewControls()->GetCursorPosition() );
983 getViewControls()->SetCrossHairCursorPosition( nearest, false );
984 getViewControls()->WarpMouseCursor( getViewControls()->GetCursorPosition(), true );
985 }
986 }
987
988 switch( type )
989 {
990 case SCH_NO_CONNECT_T:
991 previewItem = new SCH_NO_CONNECT( cursorPos );
992 previewItem->SetParent( screen );
993 description = _( "Add No Connect Flag" );
994 allowRepeat = true;
995 break;
996
997 case SCH_JUNCTION_T:
998 previewItem = new SCH_JUNCTION( cursorPos );
999 previewItem->SetParent( screen );
1000 description = _( "Add Junction" );
1001 break;
1002
1004 previewItem = new SCH_BUS_WIRE_ENTRY( cursorPos );
1005 previewItem->SetParent( screen );
1006 description = _( "Add Wire to Bus Entry" );
1007 allowRepeat = true;
1008 break;
1009
1010 default:
1011 wxASSERT_MSG( false, "Unknown item type in SCH_DRAWING_TOOLS::SingleClickPlace" );
1012 return 0;
1013 }
1014
1016
1017 cursorPos = aEvent.HasPosition() ? aEvent.Position() : controls->GetMousePosition();
1018
1019 m_frame->PushTool( aEvent );
1020
1021 auto setCursor =
1022 [&]()
1023 {
1024 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PLACE );
1025 };
1026
1027 Activate();
1028
1029 // Must be done after Activate() so that it gets set into the correct context
1030 getViewControls()->ShowCursor( true );
1031
1032 // Set initial cursor
1033 setCursor();
1034
1036 m_view->AddToPreview( previewItem->Clone() );
1037
1038 // Prime the pump
1039 if( aEvent.HasPosition() && type != SCH_SHEET_PIN_T )
1040 m_toolMgr->PrimeTool( aEvent.Position() );
1041 else
1043
1044 // Main loop: keep receiving events
1045 while( TOOL_EVENT* evt = Wait() )
1046 {
1047 setCursor();
1048 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1049 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1050
1051 cursorPos = evt->IsPrime() ? evt->Position() : controls->GetMousePosition();
1052 cursorPos = grid.BestSnapAnchor( cursorPos, grid.GetItemGrid( previewItem ), nullptr );
1053 controls->ForceCursorPosition( true, cursorPos );
1054
1055 if( evt->IsCancelInteractive() )
1056 {
1057 m_frame->PopTool( aEvent );
1058 break;
1059 }
1060 else if( evt->IsActivate() )
1061 {
1062 if( evt->IsMoveTool() )
1063 {
1064 // leave ourselves on the stack so we come back after the move
1065 break;
1066 }
1067 else
1068 {
1069 m_frame->PopTool( aEvent );
1070 break;
1071 }
1072 }
1073 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1074 {
1075 if( !screen->GetItem( cursorPos, 0, type ) )
1076 {
1077 if( type == SCH_JUNCTION_T )
1078 {
1079 if( !screen->IsExplicitJunctionAllowed( cursorPos ) )
1080 {
1081 m_frame->ShowInfoBarError( _( "Junction location contains no joinable "
1082 "wires and/or pins." ) );
1083 loggedInfoBarError = true;
1084 continue;
1085 }
1086 else if( loggedInfoBarError )
1087 {
1089 }
1090 }
1091
1092 SCH_ITEM* newItem = static_cast<SCH_ITEM*>( previewItem->Clone() );
1093 const_cast<KIID&>( newItem->m_Uuid ) = KIID();
1094 newItem->SetPosition( cursorPos );
1095 newItem->SetFlags( IS_NEW );
1096 m_frame->AddToScreen( newItem, screen );
1097
1098 if( allowRepeat )
1099 m_frame->SaveCopyForRepeatItem( newItem );
1100
1101 SCH_COMMIT commit( m_toolMgr );
1102 commit.Added( newItem, screen );
1103
1104 m_frame->SchematicCleanUp( &commit );
1105
1106 commit.Push( description );
1107 }
1108
1109 if( evt->IsDblClick( BUT_LEFT ) || type == SCH_SHEET_PIN_T ) // Finish tool.
1110 {
1111 m_frame->PopTool( aEvent );
1112 break;
1113 }
1114 }
1115 else if( evt->IsClick( BUT_RIGHT ) )
1116 {
1118 }
1119 else if( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() )
1120 {
1121 previewItem->SetPosition( cursorPos );
1123 m_view->AddToPreview( previewItem->Clone() );
1124 m_frame->SetMsgPanel( previewItem );
1125 }
1126 else if( evt->Category() == TC_COMMAND )
1127 {
1128 if( ( type == SCH_BUS_WIRE_ENTRY_T ) && ( evt->IsAction( &EE_ACTIONS::rotateCW )
1129 || evt->IsAction( &EE_ACTIONS::rotateCCW )
1130 || evt->IsAction( &EE_ACTIONS::mirrorV )
1131 || evt->IsAction( &EE_ACTIONS::mirrorH ) ) )
1132 {
1133 SCH_BUS_ENTRY_BASE* busItem = static_cast<SCH_BUS_ENTRY_BASE*>( previewItem );
1134
1135 if( evt->IsAction( &EE_ACTIONS::rotateCW ) )
1136 {
1137 busItem->Rotate( busItem->GetPosition(), false );
1138 }
1139 else if( evt->IsAction( &EE_ACTIONS::rotateCCW ) )
1140 {
1141 busItem->Rotate( busItem->GetPosition(), true );
1142 }
1143 else if( evt->IsAction( &EE_ACTIONS::mirrorV ) )
1144 {
1145 busItem->MirrorVertically( busItem->GetPosition().y );
1146 }
1147 else if( evt->IsAction( &EE_ACTIONS::mirrorH ) )
1148 {
1149 busItem->MirrorHorizontally( busItem->GetPosition().x );
1150 }
1151
1153 m_view->AddToPreview( previewItem->Clone() );
1154 }
1155 else if( evt->IsAction( &EE_ACTIONS::properties ) )
1156 {
1157 switch( type )
1158 {
1160 {
1161 std::deque<SCH_ITEM*> strokeItems;
1162 strokeItems.push_back( previewItem );
1163
1164 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, strokeItems );
1165 }
1166 break;
1167
1168 case SCH_JUNCTION_T:
1169 {
1170 std::deque<SCH_JUNCTION*> junctions;
1171 junctions.push_back( static_cast<SCH_JUNCTION*>( previewItem ) );
1172
1173 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1174 }
1175 break;
1176 default:
1177 // Do nothing
1178 break;
1179 }
1180
1182 m_view->AddToPreview( previewItem->Clone() );
1183 }
1184 else
1185 {
1186 evt->SetPassEvent();
1187 }
1188 }
1189 else
1190 {
1191 evt->SetPassEvent();
1192 }
1193 }
1194
1195 delete previewItem;
1197
1198 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1199 controls->ForceCursorPosition( false );
1200
1201 return 0;
1202}
1203
1204
1206{
1207 for( SCH_ITEM* item : m_frame->GetScreen()->Items().Overlapping( SCH_LINE_T, aPosition ) )
1208 {
1209 SCH_LINE* line = static_cast<SCH_LINE*>( item );
1210
1211 if( line->GetEditFlags() & STRUCT_DELETED )
1212 continue;
1213
1214 if( line->IsWire() )
1215 return line;
1216 }
1217
1218 return nullptr;
1219}
1220
1221
1223{
1224 wxASSERT( aWire->IsWire() );
1225
1226 SCH_SHEET_PATH sheetPath = m_frame->GetCurrentSheet();
1227
1228 if( SCH_CONNECTION* wireConnection = aWire->Connection( &sheetPath ) )
1229 {
1230 SCH_ITEM* wireDriver = wireConnection->Driver();
1231
1232 if( wireDriver && wireDriver->IsType( { SCH_LABEL_T, SCH_GLOBAL_LABEL_T } ) )
1233 return wireConnection->LocalName();
1234 }
1235
1236 return wxEmptyString;
1237}
1238
1239
1241{
1242 SCHEMATIC* schematic = getModel<SCHEMATIC>();
1243 SCHEMATIC_SETTINGS& settings = schematic->Settings();
1244 SCH_TEXT* textItem = nullptr;
1245 SCH_LABEL_BASE* labelItem = nullptr;
1246 wxString netName;
1247
1248 switch( aType )
1249 {
1250 case LAYER_NOTES:
1251 textItem = new SCH_TEXT( aPosition );
1252 break;
1253
1254 case LAYER_LOCLABEL:
1255 labelItem = new SCH_LABEL( aPosition );
1256 textItem = labelItem;
1257
1258 if( SCH_LINE* wire = findWire( aPosition ) )
1259 netName = findWireLabelDriverName( wire );
1260
1261 break;
1262
1264 labelItem = new SCH_DIRECTIVE_LABEL( aPosition );
1265 labelItem->SetShape( m_lastNetClassFlagShape );
1266 labelItem->GetFields().emplace_back( SCH_FIELD( {0,0}, 0, labelItem, wxT( "Netclass" ) ) );
1267 labelItem->GetFields().back().SetItalic( true );
1268 labelItem->GetFields().back().SetVisible( true );
1269 textItem = labelItem;
1270 break;
1271
1272 case LAYER_HIERLABEL:
1273 labelItem = new SCH_HIERLABEL( aPosition );
1274 labelItem->SetShape( m_lastGlobalLabelShape );
1276 textItem = labelItem;
1277 break;
1278
1279 case LAYER_GLOBLABEL:
1280 labelItem = new SCH_GLOBALLABEL( aPosition );
1281 labelItem->SetShape( m_lastGlobalLabelShape );
1282 labelItem->GetFields()[0].SetVisible( settings.m_IntersheetRefsShow );
1284 textItem = labelItem;
1285
1286 if( SCH_LINE* wire = findWire( aPosition ) )
1287 netName = findWireLabelDriverName( wire );
1288
1289 break;
1290
1291 default:
1292 wxFAIL_MSG( "SCH_EDIT_FRAME::CreateNewText() unknown layer type" );
1293 return nullptr;
1294 }
1295
1296 textItem->SetParent( schematic );
1297
1298 textItem->SetTextSize( VECTOR2I( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
1299
1300 if( aType != LAYER_NETCLASS_REFS )
1301 {
1302 // Must be after SetTextSize()
1303 textItem->SetBold( m_lastTextBold );
1304 textItem->SetItalic( m_lastTextItalic );
1305 }
1306
1307 if( labelItem )
1308 {
1309 labelItem->SetSpinStyle( m_lastTextOrientation );
1310 }
1311 else
1312 {
1315 textItem->SetTextAngle( m_lastTextAngle );
1316 }
1317
1318 textItem->SetFlags( IS_NEW | IS_MOVING );
1319
1320 if( !labelItem )
1321 {
1322 DIALOG_TEXT_PROPERTIES dlg( m_frame, textItem );
1323
1324 // QuasiModal required for syntax help and Scintilla auto-complete
1325 if( dlg.ShowQuasiModal() != wxID_OK )
1326 {
1327 delete textItem;
1328 return nullptr;
1329 }
1330 }
1331 else if( !netName.IsEmpty() )
1332 {
1333 // Auto-create from attached wire
1334 textItem->SetText( netName );
1335 }
1336 else
1337 {
1338 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( textItem ) );
1339
1340 // QuasiModal required for syntax help and Scintilla auto-complete
1341 if( dlg.ShowQuasiModal() != wxID_OK )
1342 {
1343 delete labelItem;
1344 return nullptr;
1345 }
1346 }
1347
1348 wxString text = textItem->GetText();
1349
1350 if( textItem->Type() != SCH_DIRECTIVE_LABEL_T && NoPrintableChars( text ) )
1351 {
1352 delete textItem;
1353 return nullptr;
1354 }
1355
1356 if( aType != LAYER_NETCLASS_REFS )
1357 {
1358 m_lastTextBold = textItem->IsBold();
1359 m_lastTextItalic = textItem->IsItalic();
1360 }
1361
1362 if( labelItem )
1363 {
1364 m_lastTextOrientation = labelItem->GetSpinStyle();
1365 }
1366 else
1367 {
1368 m_lastTextHJustify = textItem->GetHorizJustify();
1369 m_lastTextVJustify = textItem->GetVertJustify();
1370 m_lastTextAngle = textItem->GetTextAngle();
1371 }
1372
1373 if( aType == LAYER_GLOBLABEL || aType == LAYER_HIERLABEL )
1374 {
1375 m_lastGlobalLabelShape = labelItem->GetShape();
1377 }
1378 else if( aType == LAYER_NETCLASS_REFS )
1379 {
1380 m_lastNetClassFlagShape = labelItem->GetShape();
1381 }
1382
1383 return textItem;
1384}
1385
1387{
1388 SCHEMATIC_SETTINGS& settings = aSheet->Schematic()->Settings();
1389 SCH_SHEET_PIN* pin = new SCH_SHEET_PIN( aSheet );
1390
1391 pin->SetFlags( IS_NEW | IS_MOVING );
1392 pin->SetText( std::to_string( aSheet->GetPins().size() + 1 ) );
1393 pin->SetTextSize( VECTOR2I( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
1394 pin->SetPosition( aPosition );
1395 pin->ClearSelected();
1396
1397 m_lastSheetPinType = pin->GetShape();
1398
1399 return pin;
1400}
1401
1402
1404{
1405 SCH_ITEM* item = nullptr;
1408 bool ignorePrimePosition = false;
1409 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
1410 SCH_SHEET* sheet = nullptr;
1411 wxString description;
1412
1413 if( m_inDrawingTool )
1414 return 0;
1415
1417
1418 bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText );
1419 bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel );
1420 bool isHierLabel = aEvent.IsAction( &EE_ACTIONS::placeHierLabel );
1421 bool isClassLabel = aEvent.IsAction( &EE_ACTIONS::placeClassLabel );
1422 bool isNetLabel = aEvent.IsAction( &EE_ACTIONS::placeLabel );
1423 bool isSheetPin = aEvent.IsAction( &EE_ACTIONS::placeSheetPin );
1424
1425 GRID_HELPER_GRIDS snapGrid = isText ? GRID_TEXT : GRID_CONNECTABLE;
1426
1427 // If we have a selected sheet use it, otherwise try to get one under the cursor
1428 if( isSheetPin )
1429 sheet = dynamic_cast<SCH_SHEET*>( m_selectionTool->GetSelection().Front() );
1430
1432
1433 m_frame->PushTool( aEvent );
1434
1435 auto setCursor =
1436 [&]()
1437 {
1438 if( item )
1439 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PLACE );
1440 else if( isText )
1441 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::TEXT );
1442 else if( isGlobalLabel )
1443 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::LABEL_GLOBAL );
1444 else if( isNetLabel )
1445 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::LABEL_NET );
1446 else if( isClassLabel )
1447 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::LABEL_NET ); // JEY TODO: netclass directive cursor
1448 else if( isHierLabel )
1449 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::LABEL_HIER );
1450 else
1451 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
1452 };
1453
1454 auto updatePreview =
1455 [&]()
1456 {
1458 m_view->AddToPreview( item->Clone() );
1459 item->RunOnChildren( [&]( SCH_ITEM* aChild )
1460 {
1461 m_view->AddToPreview( aChild->Clone() );
1462 } );
1463 m_frame->SetMsgPanel( item );
1464 };
1465
1466 auto cleanup =
1467 [&]()
1468 {
1471 delete item;
1472 item = nullptr;
1473 };
1474
1475 Activate();
1476
1477 // Must be done after Activate() so that it gets set into the correct context
1478 controls->ShowCursor( true );
1479
1480 // Set initial cursor
1481 setCursor();
1482
1483 if( aEvent.HasPosition() )
1484 {
1485 m_toolMgr->PrimeTool( aEvent.Position() );
1486 }
1487 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate()
1488 && ( isText || isGlobalLabel || isHierLabel || isClassLabel || isNetLabel ) )
1489 {
1490 m_toolMgr->PrimeTool( { 0, 0 } );
1491 ignorePrimePosition = true;
1492 }
1493
1494 // Main loop: keep receiving events
1495 while( TOOL_EVENT* evt = Wait() )
1496 {
1497 setCursor();
1498 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1499 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1500
1501 VECTOR2I cursorPos = controls->GetMousePosition();
1502 cursorPos = grid.BestSnapAnchor( cursorPos, snapGrid, item );
1503 controls->ForceCursorPosition( true, cursorPos );
1504
1505 // The tool hotkey is interpreted as a click when drawing
1506 bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
1507 && evt->Matches( aEvent );
1508
1509 if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
1510 {
1512
1513 if( item )
1514 {
1515 cleanup();
1516 }
1517 else
1518 {
1519 m_frame->PopTool( aEvent );
1520 break;
1521 }
1522 }
1523 else if( evt->IsActivate() && !isSyntheticClick )
1524 {
1525 if( item && evt->IsMoveTool() )
1526 {
1527 // we're already moving our own item; ignore the move tool
1528 evt->SetPassEvent( false );
1529 continue;
1530 }
1531
1532 if( item )
1533 {
1534 m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel item creation." ) );
1535 evt->SetPassEvent( false );
1536 continue;
1537 }
1538
1539 if( evt->IsPointEditor() )
1540 {
1541 // don't exit (the point editor runs in the background)
1542 }
1543 else if( evt->IsMoveTool() )
1544 {
1545 // leave ourselves on the stack so we come back after the move
1546 break;
1547 }
1548 else
1549 {
1550 m_frame->PopTool( aEvent );
1551 break;
1552 }
1553 }
1554 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
1555 {
1556 // First click creates...
1557 if( !item )
1558 {
1560
1561 if( isText )
1562 {
1563 item = createNewText( cursorPos, LAYER_NOTES );
1564 description = _( "Add Text" );
1565 }
1566 else if( isHierLabel )
1567 {
1568 if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
1569 {
1570 auto pin = static_cast<SCH_HIERLABEL*>(
1571 m_dialogSyncSheetPin->GetPlacementTemplate() );
1572 SCH_HIERLABEL* label = new SCH_HIERLABEL( cursorPos );
1573 SCHEMATIC* schematic = getModel<SCHEMATIC>();
1574 label->SetText( pin->GetText() );
1575 label->SetShape( pin->GetShape() );
1577 label->SetParent( schematic );
1578 label->SetBold( m_lastTextBold );
1579 label->SetItalic( m_lastTextItalic );
1581 label->SetTextSize( VECTOR2I( schematic->Settings().m_DefaultTextSize,
1582 schematic->Settings().m_DefaultTextSize ) );
1583 label->SetFlags( IS_NEW | IS_MOVING );
1584 item = label;
1585 }
1586 else
1587 {
1588 item = createNewText( cursorPos, LAYER_HIERLABEL );
1589 }
1590
1591 description = _( "Add Hierarchical Label" );
1592 }
1593 else if( isNetLabel )
1594 {
1595 item = createNewText( cursorPos, LAYER_LOCLABEL );
1596 description = _( "Add Label" );
1597 }
1598 else if( isGlobalLabel )
1599 {
1600 item = createNewText( cursorPos, LAYER_GLOBLABEL );
1601 description = _( "Add Label" );
1602 }
1603 else if( isClassLabel )
1604 {
1605 item = createNewText( cursorPos, LAYER_NETCLASS_REFS );
1606 description = _( "Add Label" );
1607 }
1608 else if( isSheetPin )
1609 {
1610 EDA_ITEM* i = nullptr;
1611
1612 // If we didn't have a sheet selected, try to find one under the cursor
1613 if( !sheet && m_selectionTool->SelectPoint( cursorPos, { SCH_SHEET_T }, &i ) )
1614 sheet = dynamic_cast<SCH_SHEET*>( i );
1615
1616 if( !sheet )
1617 {
1618 m_statusPopup = std::make_unique<STATUS_TEXT_POPUP>( m_frame );
1619 m_statusPopup->SetText( _( "Click over a sheet." ) );
1621 + wxPoint( 20, 20 ) );
1622 m_statusPopup->PopupFor( 2000 );
1623 item = nullptr;
1624 }
1625 else
1626 {
1627 item = createNewSheetPin( sheet, cursorPos );
1628
1629 if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
1630 {
1631 auto label = static_cast<SCH_HIERLABEL*>(
1632 m_dialogSyncSheetPin->GetPlacementTemplate() );
1633 auto pin = static_cast<SCH_HIERLABEL*>( item );
1634 pin->SetText( label->GetText() );
1635 pin->SetShape( label->GetShape() );
1636 }
1637 }
1638
1639 description = _( "Add Sheet Pin" );
1640 }
1641
1642 // If we started with a hotkey which has a position then warp back to that.
1643 // Otherwise update to the current mouse position pinned inside the autoscroll
1644 // boundaries.
1645 if( evt->IsPrime() && !ignorePrimePosition )
1646 {
1647 cursorPos = grid.Align( evt->Position() );
1648 getViewControls()->WarpMouseCursor( cursorPos, true );
1649 }
1650 else
1651 {
1653 cursorPos = getViewControls()->GetMousePosition();
1654 cursorPos = grid.BestSnapAnchor( cursorPos, snapGrid, item );
1655 }
1656
1657 if( item )
1658 {
1659 item->SetPosition( cursorPos );
1660
1661 item->SetFlags( IS_NEW | IS_MOVING );
1662 item->AutoplaceFields( nullptr, false /* aManual */ );
1663 updatePreview();
1666
1667 // update the cursor so it looks correct before another event
1668 setCursor();
1669 }
1670
1671 controls->SetCursorPosition( cursorPos, false );
1672 }
1673 else // ... and second click places:
1674 {
1675 SCH_COMMIT commit( m_toolMgr );
1676
1677 item->ClearFlags( IS_MOVING );
1678
1679 if( item->IsConnectable() )
1681
1682 if( isSheetPin )
1683 {
1684 // Sheet pins are owned by their parent sheet.
1685 commit.Modify( sheet, m_frame->GetScreen() );
1686 sheet->AddPin( (SCH_SHEET_PIN*) item );
1687 }
1688 else
1689 {
1691 m_frame->AddToScreen( item, m_frame->GetScreen() );
1692 commit.Added( item, m_frame->GetScreen() );
1693 }
1694
1695 item->AutoplaceFields( m_frame->GetScreen(), false /* aManual */ );
1696
1697 commit.Push( description );
1698
1700
1701 if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
1702 {
1703 m_frame->PopTool( aEvent );
1705 m_dialogSyncSheetPin->EndPlaceItem( item );
1706 m_dialogSyncSheetPin->Show( true );
1707 break;
1708 }
1709 else
1710 {
1711 item = nullptr;
1712 }
1713
1714 if( isSheetPin )
1715 {
1716 item = createNewSheetPin( sheet, cursorPos );
1717 item->SetPosition( cursorPos );
1720 }
1721 }
1722 }
1723 else if( evt->IsClick( BUT_RIGHT ) )
1724 {
1725 // Warp after context menu only if dragging...
1726 if( !item )
1728
1730 }
1731 else if( item && evt->IsSelectionEvent() )
1732 {
1733 // This happens if our text was replaced out from under us by ConvertTextType()
1735
1736 if( selection.GetSize() == 1 )
1737 {
1738 item = (SCH_ITEM*) selection.Front();
1739 updatePreview();
1740 }
1741 else
1742 {
1743 item = nullptr;
1744 }
1745 }
1746 else if( evt->IsAction( &ACTIONS::duplicate )
1747 || evt->IsAction( &EE_ACTIONS::repeatDrawItem ) )
1748 {
1749 if( item )
1750 {
1751 // This doesn't really make sense; we'll just end up dragging a stack of
1752 // objects so we ignore the duplicate and just carry on.
1753 wxBell();
1754 continue;
1755 }
1756
1757 // Exit. The duplicate will run in its own loop.
1758 m_frame->PopTool( aEvent );
1759 break;
1760 }
1761 else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
1762 {
1763 item->SetPosition( cursorPos );
1764 item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
1765 updatePreview();
1766 }
1767 else if( item && evt->IsAction( &ACTIONS::doDelete ) )
1768 {
1769 cleanup();
1770 }
1771 else if( evt->IsAction( &ACTIONS::redo ) )
1772 {
1773 wxBell();
1774 }
1775 else
1776 {
1777 evt->SetPassEvent();
1778 }
1779
1780 // Enable autopanning and cursor capture only when there is an item to be placed
1781 controls->SetAutoPan( item != nullptr );
1782 controls->CaptureCursor( item != nullptr );
1783 }
1784
1785 controls->SetAutoPan( false );
1786 controls->CaptureCursor( false );
1787 controls->ForceCursorPosition( false );
1788 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1789
1790 if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
1791 {
1792 m_dialogSyncSheetPin->EndPlaceItem( nullptr );
1793 m_dialogSyncSheetPin->Show( true );
1794 }
1795
1796 return 0;
1797}
1798
1799
1801{
1802 SCHEMATIC* schematic = getModel<SCHEMATIC>();
1803 SCHEMATIC_SETTINGS& sch_settings = schematic->Settings();
1804 SCH_SHAPE* item = nullptr;
1805 bool isTextBox = aEvent.IsAction( &EE_ACTIONS::drawTextBox );
1806 SHAPE_T type = aEvent.Parameter<SHAPE_T>();
1807 wxString description;
1808
1809 if( m_inDrawingTool )
1810 return 0;
1811
1813
1816 VECTOR2I cursorPos;
1817
1818 // We might be running as the same shape in another co-routine. Make sure that one
1819 // gets whacked.
1821
1823
1824 m_frame->PushTool( aEvent );
1825
1826 auto setCursor =
1827 [&]()
1828 {
1829 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
1830 };
1831
1832 auto cleanup =
1833 [&] ()
1834 {
1837 delete item;
1838 item = nullptr;
1839 };
1840
1841 Activate();
1842
1843 // Must be done after Activate() so that it gets set into the correct context
1844 getViewControls()->ShowCursor( true );
1845
1846 // Set initial cursor
1847 setCursor();
1848
1849 if( aEvent.HasPosition() )
1850 m_toolMgr->PrimeTool( aEvent.Position() );
1851
1852 // Main loop: keep receiving events
1853 while( TOOL_EVENT* evt = Wait() )
1854 {
1855 setCursor();
1856 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1857 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1858
1859 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
1860 controls->ForceCursorPosition( true, cursorPos );
1861
1862 // The tool hotkey is interpreted as a click when drawing
1863 bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
1864 && evt->Matches( aEvent );
1865
1866 if( evt->IsCancelInteractive() || ( item && evt->IsAction( &ACTIONS::undo ) ) )
1867 {
1868 if( item )
1869 {
1870 cleanup();
1871 }
1872 else
1873 {
1874 m_frame->PopTool( aEvent );
1875 break;
1876 }
1877 }
1878 else if( evt->IsActivate() && !isSyntheticClick )
1879 {
1880 if( item && evt->IsMoveTool() )
1881 {
1882 // we're already drawing our own item; ignore the move tool
1883 evt->SetPassEvent( false );
1884 continue;
1885 }
1886
1887 if( item )
1888 cleanup();
1889
1890 if( evt->IsPointEditor() )
1891 {
1892 // don't exit (the point editor runs in the background)
1893 }
1894 else if( evt->IsMoveTool() )
1895 {
1896 // leave ourselves on the stack so we come back after the move
1897 break;
1898 }
1899 else
1900 {
1901 m_frame->PopTool( aEvent );
1902 break;
1903 }
1904 }
1905 else if( evt->IsClick( BUT_LEFT ) && !item )
1906 {
1908
1909 if( isTextBox )
1910 {
1912
1913 textbox->SetTextSize( VECTOR2I( sch_settings.m_DefaultTextSize,
1914 sch_settings.m_DefaultTextSize ) );
1915
1916 // Must come after SetTextSize()
1917 textbox->SetBold( m_lastTextBold );
1918 textbox->SetItalic( m_lastTextItalic );
1919
1920 textbox->SetTextAngle( m_lastTextboxAngle );
1923 textbox->SetStroke( m_lastTextboxStroke );
1925 textbox->SetParent( schematic );
1926
1927 item = textbox;
1928 description = _( "Add Text Box" );
1929 }
1930 else
1931 {
1932 item = new SCH_SHAPE( type, LAYER_NOTES, 0, m_lastFillStyle );
1933
1934 item->SetStroke( m_lastStroke );
1936 item->SetParent( schematic );
1937 description = wxString::Format( _( "Add %s" ), item->GetFriendlyName() );
1938 }
1939
1940 item->SetFlags( IS_NEW );
1941 item->BeginEdit( cursorPos );
1942
1944 m_view->AddToPreview( item->Clone() );
1945 }
1946 else if( item && ( evt->IsClick( BUT_LEFT )
1947 || evt->IsDblClick( BUT_LEFT )
1948 || isSyntheticClick
1949 || evt->IsAction( &ACTIONS::finishInteractive ) ) )
1950 {
1951 if( evt->IsDblClick( BUT_LEFT )
1952 || evt->IsAction( &ACTIONS::finishInteractive )
1953 || !item->ContinueEdit( cursorPos ) )
1954 {
1955 item->EndEdit();
1956 item->ClearEditFlags();
1957 item->SetFlags( IS_NEW );
1958
1959 if( isTextBox )
1960 {
1961 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
1962 DIALOG_TEXT_PROPERTIES dlg( m_frame, textbox );
1963
1964 getViewControls()->SetAutoPan( false );
1965 getViewControls()->CaptureCursor( false );
1966
1967 // QuasiModal required for syntax help and Scintilla auto-complete
1968 if( dlg.ShowQuasiModal() != wxID_OK )
1969 {
1970 cleanup();
1971 continue;
1972 }
1973
1974 m_lastTextBold = textbox->IsBold();
1975 m_lastTextItalic = textbox->IsItalic();
1976 m_lastTextboxAngle = textbox->GetTextAngle();
1979 m_lastTextboxStroke = textbox->GetStroke();
1982 }
1983 else
1984 {
1985 m_lastStroke = item->GetStroke();
1986 m_lastFillStyle = item->GetFillMode();
1987 m_lastFillColor = item->GetFillColor();
1988 }
1989
1990 SCH_COMMIT commit( m_toolMgr );
1991 commit.Add( item, m_frame->GetScreen() );
1992 commit.Push( wxString::Format( _( "Draw %s" ), item->GetClass() ) );
1993
1995 item = nullptr;
1996
1999 }
2000 }
2001 else if( evt->IsAction( &ACTIONS::duplicate )
2002 || evt->IsAction( &EE_ACTIONS::repeatDrawItem ) )
2003 {
2004 if( item )
2005 {
2006 // This doesn't really make sense; we'll just end up dragging a stack of
2007 // objects so we ignore the duplicate and just carry on.
2008 wxBell();
2009 continue;
2010 }
2011
2012 // Exit. The duplicate will run in its own loop.
2013 m_frame->PopTool( aEvent );
2014 break;
2015 }
2016 else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
2017 {
2018 item->CalcEdit( cursorPos );
2020 m_view->AddToPreview( item->Clone() );
2021 m_frame->SetMsgPanel( item );
2022 }
2023 else if( evt->IsDblClick( BUT_LEFT ) && !item )
2024 {
2026 }
2027 else if( evt->IsClick( BUT_RIGHT ) )
2028 {
2029 // Warp after context menu only if dragging...
2030 if( !item )
2032
2034 }
2035 else if( item && evt->IsAction( &ACTIONS::redo ) )
2036 {
2037 wxBell();
2038 }
2039 else
2040 {
2041 evt->SetPassEvent();
2042 }
2043
2044 // Enable autopanning and cursor capture only when there is a shape being drawn
2045 getViewControls()->SetAutoPan( item != nullptr );
2046 getViewControls()->CaptureCursor( item != nullptr );
2047 }
2048
2049 getViewControls()->SetAutoPan( false );
2050 getViewControls()->CaptureCursor( false );
2051 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
2052 return 0;
2053}
2054
2055
2057{
2058 if( m_inDrawingTool )
2059 return 0;
2060
2062 SCOPED_SET_RESET<bool> scopedDrawMode( m_drawingRuleArea, true );
2063
2066 VECTOR2I cursorPos;
2067
2068 RULE_AREA_CREATE_HELPER ruleAreaTool( *getView(), m_frame, m_toolMgr );
2069 POLYGON_GEOM_MANAGER polyGeomMgr( ruleAreaTool );
2070 bool started = false;
2071
2072 // We might be running as the same shape in another co-routine. Make sure that one
2073 // gets whacked.
2075
2077
2078 m_frame->PushTool( aEvent );
2079
2080 auto setCursor =
2081 [&]()
2082 {
2083 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
2084 };
2085
2086 auto cleanup = [&]()
2087 {
2088 polyGeomMgr.Reset();
2089 started = false;
2090 getViewControls()->SetAutoPan( false );
2091 getViewControls()->CaptureCursor( false );
2093 };
2094
2095 Activate();
2096
2097 // Must be done after Activate() so that it gets set into the correct context
2098 getViewControls()->ShowCursor( true );
2099 //m_controls->ForceCursorPosition( false );
2100
2101 // Set initial cursor
2102 setCursor();
2103
2104 if( aEvent.HasPosition() )
2105 m_toolMgr->PrimeTool( aEvent.Position() );
2106
2107 // Main loop: keep receiving events
2108 while( TOOL_EVENT* evt = Wait() )
2109 {
2110 setCursor();
2111
2112 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
2113 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
2114
2115 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_CONNECTABLE );
2116 controls->ForceCursorPosition( true, cursorPos );
2117
2121
2122 if( evt->IsCancelInteractive() )
2123 {
2124 if( started )
2125 {
2126 cleanup();
2127 }
2128 else
2129 {
2130 m_frame->PopTool( aEvent );
2131
2132 // We've handled the cancel event. Don't cancel other tools
2133 evt->SetPassEvent( false );
2134 break;
2135 }
2136 }
2137 else if( evt->IsActivate() )
2138 {
2139 if( started )
2140 cleanup();
2141
2142 if( evt->IsPointEditor() )
2143 {
2144 // don't exit (the point editor runs in the background)
2145 }
2146 else if( evt->IsMoveTool() )
2147 {
2148 // leave ourselves on the stack so we come back after the move
2149 break;
2150 }
2151 else
2152 {
2153 m_frame->PopTool( aEvent );
2154 break;
2155 }
2156 }
2157 else if( evt->IsClick( BUT_RIGHT ) )
2158 {
2159 if( !started )
2161
2163 }
2164 // events that lock in nodes
2165 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
2166 || evt->IsAction( &EE_ACTIONS::closeOutline ) )
2167 {
2168 // Check if it is double click / closing line (so we have to finish the zone)
2169 const bool endPolygon = evt->IsDblClick( BUT_LEFT )
2170 || evt->IsAction( &EE_ACTIONS::closeOutline )
2171 || polyGeomMgr.NewPointClosesOutline( cursorPos );
2172
2173 if( endPolygon )
2174 {
2175 polyGeomMgr.SetFinished();
2176 polyGeomMgr.Reset();
2177
2178 started = false;
2179 getViewControls()->SetAutoPan( false );
2180 getViewControls()->CaptureCursor( false );
2181 }
2182 // adding a corner
2183 else if( polyGeomMgr.AddPoint( cursorPos ) )
2184 {
2185 if( !started )
2186 {
2187 started = true;
2188
2189 getViewControls()->SetAutoPan( true );
2190 getViewControls()->CaptureCursor( true );
2191 }
2192 }
2193 }
2194 else if( started
2195 && ( evt->IsAction( &EE_ACTIONS::deleteLastPoint )
2196 || evt->IsAction( &ACTIONS::doDelete ) || evt->IsAction( &ACTIONS::undo ) ) )
2197 {
2198 if( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
2199 {
2200 cursorPos = last.value();
2201 getViewControls()->WarpMouseCursor( cursorPos, true );
2202 getViewControls()->ForceCursorPosition( true, cursorPos );
2203 polyGeomMgr.SetCursorPosition( cursorPos );
2204 }
2205 else
2206 {
2207 cleanup();
2208 }
2209 }
2210 else if( started && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
2211 {
2212 polyGeomMgr.SetCursorPosition( cursorPos );
2213 }
2214 else
2215 {
2216 evt->SetPassEvent();
2217 }
2218
2219 } // end while
2220
2221 getViewControls()->SetAutoPan( false );
2222 getViewControls()->CaptureCursor( false );
2223 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
2224 return 0;
2225}
2226
2227
2229{
2230 SCHEMATIC* schematic = getModel<SCHEMATIC>();
2231 SCH_TABLE* table = nullptr;
2232
2233 if( m_inDrawingTool )
2234 return 0;
2235
2237
2240 VECTOR2I cursorPos;
2241
2242 // We might be running as the same shape in another co-routine. Make sure that one
2243 // gets whacked.
2245
2247
2248 m_frame->PushTool( aEvent );
2249
2250 auto setCursor =
2251 [&]()
2252 {
2253 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
2254 };
2255
2256 auto cleanup =
2257 [&] ()
2258 {
2261 delete table;
2262 table = nullptr;
2263 };
2264
2265 Activate();
2266
2267 // Must be done after Activate() so that it gets set into the correct context
2268 getViewControls()->ShowCursor( true );
2269
2270 // Set initial cursor
2271 setCursor();
2272
2273 if( aEvent.HasPosition() )
2274 m_toolMgr->PrimeTool( aEvent.Position() );
2275
2276 // Main loop: keep receiving events
2277 while( TOOL_EVENT* evt = Wait() )
2278 {
2279 setCursor();
2280 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
2281 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
2282
2283 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
2284 controls->ForceCursorPosition( true, cursorPos );
2285
2286 // The tool hotkey is interpreted as a click when drawing
2287 bool isSyntheticClick = table && evt->IsActivate() && evt->HasPosition()
2288 && evt->Matches( aEvent );
2289
2290 if( evt->IsCancelInteractive() || ( table && evt->IsAction( &ACTIONS::undo ) ) )
2291 {
2292 if( table )
2293 {
2294 cleanup();
2295 }
2296 else
2297 {
2298 m_frame->PopTool( aEvent );
2299 break;
2300 }
2301 }
2302 else if( evt->IsActivate() && !isSyntheticClick )
2303 {
2304 if( table && evt->IsMoveTool() )
2305 {
2306 // we're already drawing our own item; ignore the move tool
2307 evt->SetPassEvent( false );
2308 continue;
2309 }
2310
2311 if( table )
2312 cleanup();
2313
2314 if( evt->IsPointEditor() )
2315 {
2316 // don't exit (the point editor runs in the background)
2317 }
2318 else if( evt->IsMoveTool() )
2319 {
2320 // leave ourselves on the stack so we come back after the move
2321 break;
2322 }
2323 else
2324 {
2325 m_frame->PopTool( aEvent );
2326 break;
2327 }
2328 }
2329 else if( evt->IsClick( BUT_LEFT ) && !table )
2330 {
2332
2333 table = new SCH_TABLE( 0 );
2334 table->SetColCount( 1 );
2335 table->AddCell( new SCH_TABLECELL() );
2336
2337 table->SetParent( schematic );
2338 table->SetFlags( IS_NEW );
2339 table->SetPosition( cursorPos );
2340
2342 m_view->AddToPreview( table->Clone() );
2343 }
2344 else if( table && ( evt->IsClick( BUT_LEFT )
2345 || evt->IsDblClick( BUT_LEFT )
2346 || isSyntheticClick
2347 || evt->IsAction( &EE_ACTIONS::finishInteractive ) ) )
2348 {
2349 table->ClearEditFlags();
2350 table->SetFlags( IS_NEW );
2351 table->Normalize();
2352
2353 DIALOG_TABLE_PROPERTIES dlg( m_frame, table );
2354
2355 // QuasiModal required for Scintilla auto-complete
2356 if( dlg.ShowQuasiModal() == wxID_OK )
2357 {
2358 SCH_COMMIT commit( m_toolMgr );
2359 commit.Add( table, m_frame->GetScreen() );
2360 commit.Push( _( "Draw Table" ) );
2361
2362 m_selectionTool->AddItemToSel( table );
2364 }
2365 else
2366 {
2367 delete table;
2368 }
2369
2370 table = nullptr;
2372 }
2373 else if( table && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
2374 {
2375 VECTOR2I gridSize = grid.GetGridSize( grid.GetItemGrid( table ) );
2376 int fontSize = schematic->Settings().m_DefaultTextSize;
2377 VECTOR2I origin( table->GetPosition() );
2378 VECTOR2I requestedSize( cursorPos - origin );
2379
2380 int colCount = std::max( 1, requestedSize.x / ( fontSize * 15 ) );
2381 int rowCount = std::max( 1, requestedSize.y / ( fontSize * 2 ) );
2382
2383 VECTOR2I cellSize( std::max( gridSize.x * 5, requestedSize.x / colCount ),
2384 std::max( gridSize.y * 2, requestedSize.y / rowCount ) );
2385
2386 cellSize.x = KiROUND( (double) cellSize.x / gridSize.x ) * gridSize.x;
2387 cellSize.y = KiROUND( (double) cellSize.y / gridSize.y ) * gridSize.y;
2388
2389 table->ClearCells();
2390 table->SetColCount( colCount );
2391
2392 for( int col = 0; col < colCount; ++col )
2393 table->SetColWidth( col, cellSize.x );
2394
2395 for( int row = 0; row < rowCount; ++row )
2396 {
2397 table->SetRowHeight( row, cellSize.y );
2398
2399 for( int col = 0; col < colCount; ++col )
2400 {
2401 SCH_TABLECELL* cell = new SCH_TABLECELL();
2402 cell->SetPosition( origin + VECTOR2I( col * cellSize.x, row * cellSize.y ) );
2403 cell->SetEnd( cell->GetPosition() + cellSize );
2404 table->AddCell( cell );
2405 }
2406 }
2407
2409 m_view->AddToPreview( table->Clone() );
2410 m_frame->SetMsgPanel( table );
2411 }
2412 else if( evt->IsDblClick( BUT_LEFT ) && !table )
2413 {
2415 }
2416 else if( evt->IsClick( BUT_RIGHT ) )
2417 {
2418 // Warp after context menu only if dragging...
2419 if( !table )
2421
2423 }
2424 else if( table && evt->IsAction( &ACTIONS::redo ) )
2425 {
2426 wxBell();
2427 }
2428 else
2429 {
2430 evt->SetPassEvent();
2431 }
2432
2433 // Enable autopanning and cursor capture only when there is a shape being drawn
2434 getViewControls()->SetAutoPan( table != nullptr );
2435 getViewControls()->CaptureCursor( table != nullptr );
2436 }
2437
2438 getViewControls()->SetAutoPan( false );
2439 getViewControls()->CaptureCursor( false );
2440 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
2441 return 0;
2442}
2443
2444
2446{
2447 SCH_SHEET* sheet = nullptr;
2448
2449 if( m_inDrawingTool )
2450 return 0;
2451
2453
2456 VECTOR2I cursorPos;
2457
2459
2460 m_frame->PushTool( aEvent );
2461
2462 auto setCursor =
2463 [&]()
2464 {
2465 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
2466 };
2467
2468 auto cleanup =
2469 [&] ()
2470 {
2473 delete sheet;
2474 sheet = nullptr;
2475 };
2476
2477 Activate();
2478
2479 // Must be done after Activate() so that it gets set into the correct context
2480 getViewControls()->ShowCursor( true );
2481
2482 // Set initial cursor
2483 setCursor();
2484
2485 if( aEvent.HasPosition() )
2486 m_toolMgr->PrimeTool( aEvent.Position() );
2487
2488 // Main loop: keep receiving events
2489 while( TOOL_EVENT* evt = Wait() )
2490 {
2491 setCursor();
2492 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
2493 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
2494
2495 cursorPos = grid.Align( controls->GetMousePosition(), GRID_HELPER_GRIDS::GRID_GRAPHICS );
2496 controls->ForceCursorPosition( true, cursorPos );
2497
2498 // The tool hotkey is interpreted as a click when drawing
2499 bool isSyntheticClick = sheet && evt->IsActivate() && evt->HasPosition()
2500 && evt->Matches( aEvent );
2501
2502 if( evt->IsCancelInteractive() || ( sheet && evt->IsAction( &ACTIONS::undo ) ) )
2503 {
2505
2506 if( sheet )
2507 {
2508 cleanup();
2509 }
2510 else
2511 {
2512 m_frame->PopTool( aEvent );
2513 break;
2514 }
2515 }
2516 else if( evt->IsActivate() && !isSyntheticClick )
2517 {
2518 if( sheet && evt->IsMoveTool() )
2519 {
2520 // we're already drawing our own item; ignore the move tool
2521 evt->SetPassEvent( false );
2522 continue;
2523 }
2524
2525 if( sheet )
2526 {
2527 m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel sheet creation." ) );
2528 evt->SetPassEvent( false );
2529 continue;
2530 }
2531
2532 if( evt->IsPointEditor() )
2533 {
2534 // don't exit (the point editor runs in the background)
2535 }
2536 else if( evt->IsMoveTool() )
2537 {
2538 // leave ourselves on the stack so we come back after the move
2539 break;
2540 }
2541 else
2542 {
2543 m_frame->PopTool( aEvent );
2544 break;
2545 }
2546 }
2547 else if( !sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) )
2548 {
2551
2552 if( selection.Size() == 1
2553 && selection.Front()->Type() == SCH_SHEET_T
2554 && selection.Front()->GetBoundingBox().Contains( cursorPos ) )
2555 {
2556 if( evt->IsClick( BUT_LEFT ) )
2557 {
2558 // sheet already selected
2559 continue;
2560 }
2561 else if( evt->IsDblClick( BUT_LEFT ) )
2562 {
2564 break;
2565 }
2566 }
2567
2569
2570 sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(), cursorPos );
2571 sheet->SetFlags( IS_NEW | IS_MOVING );
2572 sheet->SetScreen( nullptr );
2576 sheet->GetFields()[ SHEETNAME ].SetText( "Untitled Sheet" );
2577 sheet->GetFields()[ SHEETFILENAME ].SetText( "untitled." + FILEEXT::KiCadSchematicFileExtension );
2578 sizeSheet( sheet, cursorPos );
2579
2581 m_view->AddToPreview( sheet->Clone() );
2582 }
2583 else if( sheet && ( evt->IsClick( BUT_LEFT )
2584 || evt->IsDblClick( BUT_LEFT )
2585 || isSyntheticClick
2586 || evt->IsAction( &ACTIONS::finishInteractive ) ) )
2587 {
2588 getViewControls()->SetAutoPan( false );
2589 getViewControls()->CaptureCursor( false );
2590
2591 if( m_frame->EditSheetProperties( static_cast<SCH_SHEET*>( sheet ),
2592 &m_frame->GetCurrentSheet() ) )
2593 {
2595
2596 sheet->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
2597
2598 SCH_COMMIT commit( m_toolMgr );
2599 commit.Add( sheet, m_frame->GetScreen() );
2600 commit.Push( "Draw Sheet" );
2601
2603 newPath.push_back( sheet );
2604
2606 m_selectionTool->AddItemToSel( sheet );
2607 }
2608 else
2609 {
2611 delete sheet;
2612 }
2613
2614 sheet = nullptr;
2615 }
2616 else if( evt->IsAction( &ACTIONS::duplicate )
2617 || evt->IsAction( &EE_ACTIONS::repeatDrawItem ) )
2618 {
2619 if( sheet )
2620 {
2621 // This doesn't really make sense; we'll just end up dragging a stack of
2622 // objects so we ignore the duplicate and just carry on.
2623 wxBell();
2624 continue;
2625 }
2626
2627 // Exit. The duplicate will run in its own loop.
2628 m_frame->PopTool( aEvent );
2629 break;
2630 }
2631 else if( sheet && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
2632 {
2633 sizeSheet( sheet, cursorPos );
2635 m_view->AddToPreview( sheet->Clone() );
2636 m_frame->SetMsgPanel( sheet );
2637 }
2638 else if( evt->IsClick( BUT_RIGHT ) )
2639 {
2640 // Warp after context menu only if dragging...
2641 if( !sheet )
2643
2645 }
2646 else if( sheet && evt->IsAction( &ACTIONS::redo ) )
2647 {
2648 wxBell();
2649 }
2650 else
2651 {
2652 evt->SetPassEvent();
2653 }
2654
2655 // Enable autopanning and cursor capture only when there is a sheet to be placed
2656 getViewControls()->SetAutoPan( sheet != nullptr );
2657 getViewControls()->CaptureCursor( sheet != nullptr );
2658 }
2659
2660 getViewControls()->SetAutoPan( false );
2661 getViewControls()->CaptureCursor( false );
2662 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
2663
2664 return 0;
2665}
2666
2667
2669{
2670 VECTOR2I pos = aSheet->GetPosition();
2671 VECTOR2I size = aPos - pos;
2672
2673 size.x = std::max( size.x, schIUScale.MilsToIU( MIN_SHEET_WIDTH ) );
2674 size.y = std::max( size.y, schIUScale.MilsToIU( MIN_SHEET_HEIGHT ) );
2675
2677 aSheet->Resize( VECTOR2I( grid.x - pos.x, grid.y - pos.y ) );
2678}
2679
2680
2681int SCH_DRAWING_TOOLS::doSyncSheetsPins( std::list<SCH_SHEET_PATH> sheetPaths )
2682{
2683 if( !sheetPaths.size() )
2684 return 0;
2685
2686 m_dialogSyncSheetPin = std::make_unique<DIALOG_SYNC_SHEET_PINS>(
2687 m_frame, std::move( sheetPaths ),
2688 std::make_shared<SHEET_SYNCHRONIZATION_AGENT>(
2689 [&]( EDA_ITEM* aItem, SCH_SHEET_PATH aPath,
2691 {
2692 SCH_COMMIT commit( m_toolMgr );
2693
2694 if( auto pin = dynamic_cast<SCH_SHEET_PIN*>( aItem ) )
2695 {
2696 commit.Modify( pin->GetParent(), aPath.LastScreen() );
2697 aModify();
2698 commit.Push( _( "Modify sheet pin" ) );
2699 }
2700 else
2701 {
2702 commit.Modify( aItem, aPath.LastScreen() );
2703 aModify();
2704 commit.Push( _( "Modify schematic item" ) );
2705 }
2706
2707 updateItem( aItem, true );
2708 m_frame->OnModify();
2709 },
2710 [&]( EDA_ITEM* aItem, SCH_SHEET_PATH aPath )
2711 {
2713 EE_ACTIONS::changeSheet, &aPath );
2715 selectionTool->UnbrightenItem( aItem );
2716 selectionTool->AddItemToSel( aItem, true );
2718 },
2719 [&]( SCH_SHEET* aItem, SCH_SHEET_PATH aPath,
2721 EDA_ITEM* aTemplate )
2722 {
2723 switch( aOp )
2724 {
2726 {
2727 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
2728 m_dialogSyncSheetPin->Hide();
2729 m_dialogSyncSheetPin->BeginPlaceItem(
2731 aTemplate );
2733 EE_ACTIONS::changeSheet, &aPath );
2735 break;
2736 }
2738 {
2739 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
2740 m_dialogSyncSheetPin->Hide();
2741 m_dialogSyncSheetPin->BeginPlaceItem(
2743 aTemplate );
2745 EE_ACTIONS::changeSheet, &aPath );
2746 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->SyncSelection( {}, nullptr,
2747 { sheet } );
2749 break;
2750 }
2751 }
2752 },
2753 m_toolMgr, m_frame ) );
2754 m_dialogSyncSheetPin->Show( true );
2755 return 0;
2756}
2757
2758
2760{
2761 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( m_selectionTool->GetSelection().Front() );
2762
2763 if( !sheet )
2764 {
2765 VECTOR2I cursorPos = getViewControls()->GetMousePosition();
2766
2767 if( EDA_ITEM* i = nullptr; static_cast<void>(m_selectionTool->SelectPoint( cursorPos, { SCH_SHEET_T }, &i ) ) , i != nullptr )
2768 {
2769 sheet = dynamic_cast<SCH_SHEET*>( i );
2770 }
2771 }
2772
2773 if ( sheet )
2774 {
2776 current.push_back( sheet );
2777 return doSyncSheetsPins( { current } );
2778 }
2779
2780 return 0;
2781}
2782
2783
2785{
2786 static const std::function<void( std::list<SCH_SHEET_PATH>&, SCH_SCREEN*,
2787 std::set<SCH_SCREEN*>&, SCH_SHEET_PATH const& )>
2788 getSheetChildren = []( std::list<SCH_SHEET_PATH>& aPaths, SCH_SCREEN* aScene,
2789 std::set<SCH_SCREEN*>& aVisited, SCH_SHEET_PATH const& aCurPath )
2790 {
2791 if( ! aScene || aVisited.find(aScene) != aVisited.end() )
2792 return ;
2793
2794 std::vector<SCH_ITEM*> sheetChildren;
2795 aScene->GetSheets( &sheetChildren );
2796 aVisited.insert( aScene );
2797
2798 for( SCH_ITEM* child : sheetChildren )
2799 {
2800 SCH_SHEET_PATH cp = aCurPath;
2801 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( child );
2802 cp.push_back( sheet );
2803 aPaths.push_back( cp );
2804 getSheetChildren( aPaths, sheet->GetScreen(), aVisited, cp );
2805 }
2806 };
2807
2808 std::list<SCH_SHEET_PATH> sheetPaths;
2809 std::set<SCH_SCREEN*> visited;
2810 SCH_SHEET_PATH current;
2811 current.push_back( &m_frame->Schematic().Root() );
2812 getSheetChildren( sheetPaths, m_frame->Schematic().Root().GetScreen(), visited, current );
2813 return doSyncSheetsPins( std::move( sheetPaths ) );
2814}
2815
2816
2818{
2841}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static TOOL_ACTION undo
Definition: actions.h:68
static TOOL_ACTION duplicate
Definition: actions.h:76
static TOOL_ACTION activatePointEditor
Definition: actions.h:210
static TOOL_ACTION doDelete
Definition: actions.h:77
static TOOL_ACTION redo
Definition: actions.h:69
static TOOL_ACTION refreshPreview
Definition: actions.h:139
static TOOL_ACTION finishInteractive
Definition: actions.h:66
bool Contains(const Vec &aPoint) const
Definition: box2.h:158
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition: commit.h:86
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
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.
std::list< std::unique_ptr< EDA_ITEM > > & GetImportedItems()
int ShowQuasiModal()
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...
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...
WX_INFOBAR * GetInfoBar()
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
VECTOR2I GetNearestGridPosition(const VECTOR2I &aPosition) const
Return the nearest aGridSize location to aPosition.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual void ClearEditFlags()
Definition: eda_item.h:141
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:244
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
const KIID m_Uuid
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:129
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:377
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
virtual wxString GetFriendlyName() const
Definition: eda_item.cpp:329
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:82
FILL_T GetFillMode() const
Definition: eda_shape.h:107
void SetFillColor(const COLOR4D &aColor)
Definition: eda_shape.h:112
COLOR4D GetFillColor() const
Definition: eda_shape.h:111
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:171
bool IsItalic() const
Definition: eda_text.h:140
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:130
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:373
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:275
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
void SetBold(bool aBold)
Definition: eda_text.cpp:220
bool IsBold() const
Definition: eda_text.h:144
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:163
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:182
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:204
void SetItalic(bool aItalic)
Definition: eda_text.cpp:212
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:267
PANEL_ANNOTATE m_AnnotatePanel
PANEL_SYM_CHOOSER m_SymChooserPanel
AUTOPLACE_FIELDS m_AutoplaceFields
static TOOL_ACTION mirrorV
Definition: ee_actions.h:126
static TOOL_ACTION properties
Definition: ee_actions.h:129
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: ee_actions.h:63
static TOOL_ACTION changeSheet
Definition: ee_actions.h:217
static TOOL_ACTION drawTable
Definition: ee_actions.h:99
static TOOL_ACTION syncAllSheetsPins
Definition: ee_actions.h:96
static TOOL_ACTION placeSymbol
Definition: ee_actions.h:79
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION drawRuleArea
Definition: ee_actions.h:107
static TOOL_ACTION placeClassLabel
Definition: ee_actions.h:88
static TOOL_ACTION closeOutline
Definition: ee_actions.h:109
static TOOL_ACTION drawCircle
Definition: ee_actions.h:101
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:125
static TOOL_ACTION placePower
Definition: ee_actions.h:80
static TOOL_ACTION deleteLastPoint
Definition: ee_actions.h:108
static TOOL_ACTION placeSheetPin
Definition: ee_actions.h:92
static TOOL_ACTION mirrorH
Definition: ee_actions.h:127
static TOOL_ACTION syncSheetPins
Definition: ee_actions.h:94
static TOOL_ACTION rotateCW
Definition: ee_actions.h:124
static TOOL_ACTION importGraphics
Definition: ee_actions.h:254
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:219
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:89
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:90
static TOOL_ACTION drawTextBox
Definition: ee_actions.h:98
static TOOL_ACTION drawRectangle
Definition: ee_actions.h:100
static TOOL_ACTION placeImage
Definition: ee_actions.h:104
static TOOL_ACTION enterSheet
Definition: ee_actions.h:218
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:97
static TOOL_ACTION drawArc
Definition: ee_actions.h:102
static TOOL_ACTION drawSheet
Definition: ee_actions.h:91
static TOOL_ACTION placeLabel
Definition: ee_actions.h:87
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:123
static TOOL_ACTION placeBusWireEntry
Definition: ee_actions.h:86
static TOOL_ACTION placeJunction
Definition: ee_actions.h:85
static TOOL_ACTION placeNoConnect
Definition: ee_actions.h:84
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:243
bool SelectPoint(const VECTOR2I &aWhere, const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, EDA_ITEM **aItem=nullptr, bool *aSelectionCancelledFlag=nullptr, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Perform a click-type selection at a point (usually the cursor position).
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
EE_SELECTION & GetSelection()
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:48
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:109
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:200
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:64
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
virtual void WarpMouseCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
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.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
virtual void PinCursorInsideNonAutoscrollArea(bool aWarpMouseCursor)=0
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:317
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:357
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:1687
void ClearPreview()
Definition: view.cpp:1709
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1454
void AddToPreview(VIEW_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1731
Definition: kiid.h:49
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
UTF8 Format() const
Definition: lib_id.cpp:118
Define a library symbol object.
Definition: lib_symbol.h:78
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:143
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:678
Class that handles the drawing of a polygon, including management of last corner deletion and drawing...
bool AddPoint(const VECTOR2I &aPt)
Lock in a polygon point.
@ DIRECT
Unconstrained point-to-point.
void SetCursorPosition(const VECTOR2I &aPos)
Set the current cursor position.
bool NewPointClosesOutline(const VECTOR2I &aPt) const
std::optional< VECTOR2I > DeleteLastCorner()
Remove the last-added point from the polygon.
void SetFinished()
Mark the polygon finished and update the client.
void SetLeaderMode(LEADER_MODE aMode)
Set the leader mode to use when calculating the leader/returner lines.
void Reset()
Clear the manager state and start again.
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
static SYMBOL_LIBS * SchLibs(PROJECT *aProject)
Definition: project_sch.cpp:90
An adjunct helper to the DRAWING_TOOL interactive tool, which handles incoming geometry changes from ...
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition: schematic.h:76
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:297
SCH_SHEET & Root() const
Definition: schematic.h:113
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const override
Definition: schematic.h:96
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PICKED_SYMBOL PickSymbolFromLibrary(const SYMBOL_LIBRARY_FILTER *aFilter, std::vector< PICKED_SYMBOL > &aHistoryList, std::vector< PICKED_SYMBOL > &aAlreadyPlaced, bool aShowFootprints, const LIB_ID *aHighlight=nullptr, bool aAllowFields=true)
Call the library viewer to select symbol to import into schematic.
Definition: picksymbol.cpp:49
EESCHEMA_SETTINGS * eeconfig() const
LIB_SYMBOL * GetLibSymbol(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:41
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:38
VECTOR2I GetPosition() const override
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Class for a wire to bus entry.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:406
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
STROKE_PARAMS m_lastTextboxStroke
GR_TEXT_V_ALIGN_T m_lastTextboxVJustify
int DrawSheet(const TOOL_EVENT &aEvent)
SPIN_STYLE m_lastTextOrientation
int SyncSheetsPins(const TOOL_EVENT &aEvent)
STROKE_PARAMS m_lastStroke
SCH_TEXT * createNewText(const VECTOR2I &aPosition, int aType)
GR_TEXT_H_ALIGN_T m_lastTextboxHJustify
std::vector< PICKED_SYMBOL > m_powerHistoryList
int SingleClickPlace(const TOOL_EVENT &aEvent)
SCH_LINE * findWire(const VECTOR2I &aPosition)
Gets the (global) label name driving this wire, if it is driven by a label.
void sizeSheet(SCH_SHEET *aSheet, const VECTOR2I &aPos)
Set up handlers for various events.
LABEL_FLAG_SHAPE m_lastGlobalLabelShape
LABEL_FLAG_SHAPE m_lastNetClassFlagShape
GR_TEXT_H_ALIGN_T m_lastTextHJustify
int ImportGraphics(const TOOL_EVENT &aEvent)
EDA_ANGLE m_lastTextboxAngle
int DrawRuleArea(const TOOL_EVENT &aEvent)
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
int TwoClickPlace(const TOOL_EVENT &aEvent)
SCH_SHEET_PIN * createNewSheetPin(SCH_SHEET *aSheet, const VECTOR2I &aPosition)
int SyncAllSheetsPins(const TOOL_EVENT &aEvent)
wxString findWireLabelDriverName(SCH_LINE *aWire)
int DrawTable(const TOOL_EVENT &aEvent)
GR_TEXT_V_ALIGN_T m_lastTextVJustify
int doSyncSheetsPins(std::list< SCH_SHEET_PATH > aSheets)
LABEL_FLAG_SHAPE m_lastSheetPinType
int DrawShape(const TOOL_EVENT &aEvent)
std::unique_ptr< DIALOG_SYNC_SHEET_PINS > m_dialogSyncSheetPin
bool Init() override
Init() is called once upon a registration of the tool.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int PlaceSymbol(const TOOL_EVENT &aEvent)
int PlaceImage(const TOOL_EVENT &aEvent)
std::vector< PICKED_SYMBOL > m_symbolHistoryList
Schematic editor (Eeschema) main window.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aIsUndoable=nullptr, bool *aClearAnnotationNewItems=nullptr, bool *aUpdateHierarchyNavigator=nullptr)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:593
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SchematicCleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void UpdateHierarchyNavigator(bool aRefreshNetNavigator=true)
Update the hierarchy navigation tree and history.
SCH_SHEET_PATH & GetCurrentSheet() const
SCHEMATIC & Schematic() const
void FlipBodyStyle(SCH_SYMBOL *aSymbol)
Definition: picksymbol.cpp:126
void SelectUnit(SCH_SYMBOL *aSymbol, int aUnit)
Definition: picksymbol.cpp:93
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:2060
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
virtual bool IsConnectable() const
Definition: sch_item.h:449
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
int GetBodyStyle() const
Definition: sch_item.h:232
int GetUnit() const
Definition: sch_item.h:229
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
Definition: sch_item.h:568
virtual void SetUnit(int aUnit)
Definition: sch_item.h:228
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:566
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:221
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:131
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:181
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1429
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:383
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:178
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:177
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1435
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:201
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:348
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.)
int AddJunctionsIfNeeded(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Handle the addition of junctions to a selection of objects.
int TrimOverLappingWires(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Logic to remove wires when overlapping correct items.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:976
VECTOR2I GetEndPoint() const
Definition: sch_line.h:141
VECTOR2I GetStartPoint() const
Definition: sch_line.h:136
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SortByReferenceOnly()
Sort the list of references by reference.
void ReannotateByOptions(ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption, int aStartNumber, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent, SCH_SHEET_LIST *aHierarchy)
Forces reannotation of the provided references.
size_t GetCount() const
void AddItem(const SCH_REFERENCE &aItem)
void UpdateAnnotation()
Update the symbol references for the schematic project (or the current sheet).
A helper to define a symbol's reference designator in a schematic.
bool AlwaysAnnotate() const
Verify the reference should always be automatically annotated.
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
SCH_ITEM * GetItem(const VECTOR2I &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:391
bool IsExplicitJunctionAllowed(const VECTOR2I &aPosition) const
Indicates that a juction dot may be placed at the given location.
Definition: sch_screen.cpp:505
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:71
void BeginEdit(const VECTOR2I &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
Definition: sch_shape.h:75
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_shape.cpp:46
void EndEdit(bool aClosed=false) override
End an object editing action.
Definition: sch_shape.h:78
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_shape.cpp:63
bool ContinueEdit(const VECTOR2I &aPosition) override
Continue an edit in progress at aPosition.
Definition: sch_shape.h:76
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: sch_shape.h:77
wxString GetClass() const override
Return the class name.
Definition: sch_shape.h:42
STROKE_PARAMS GetStroke() const override
Definition: sch_shape.h:55
VECTOR2I GetPosition() const override
Definition: sch_shape.h:70
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
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 GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
SCH_SCREEN * LastScreen()
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:119
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
Definition: sch_sheet.cpp:426
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_sheet.cpp:166
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_sheet.cpp:1027
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:93
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:122
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:110
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:400
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:172
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:663
void SetBorderWidth(int aWidth)
Definition: sch_sheet.h:116
void Resize(const VECTOR2I &aSize)
Resize this sheet to aSize and adjust all of the labels accordingly.
Definition: sch_sheet.cpp:1010
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:181
Schematic symbol object.
Definition: sch_symbol.h:106
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Automatically orient all the fields in the symbol.
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_symbol.h:823
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear exiting symbol annotation.
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:195
int GetUnitCount() const override
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:466
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:876
void SetRowHeight(int aRow, int aHeight)
Definition: sch_table.h:121
void SetColCount(int aCount)
Definition: sch_table.h:103
void SetColWidth(int aCol, int aWidth)
Definition: sch_table.h:111
void AddCell(SCH_TABLECELL *aCell)
Definition: sch_table.h:146
VECTOR2I GetPosition() const override
Definition: sch_table.cpp:115
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_table.h:188
void ClearCells()
Definition: sch_table.h:158
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_table.h:210
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_table.cpp:109
void Normalize()
Definition: sch_table.cpp:135
RAII class that sets an value at construction and resets it to the original value at destruction.
Definition: seg.h:42
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:327
int AddItemToSel(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:42
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:100
EDA_ITEM * Front() const
Definition: selection.h:172
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:93
int Size() const
Returns the number of selected parts.
Definition: selection.h:116
Helper object to filter a list of libraries.
SYMBOL_LIB * GetCacheLibrary()
Object used to load, save, search, and otherwise manipulate symbol library files.
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:218
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool HasPosition() const
Definition: tool_event.h:256
bool DisableGridSnapping() const
Definition: tool_event.h:363
const VECTOR2D Position() const
Returns the point where dragging has started.
Definition: tool_event.h:285
bool IsReactivate() const
Definition: tool_event.h:268
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:82
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:460
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).
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
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 Activate()
Run the tool.
void DeactivateTool()
Deactivate the currently active tool.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
void PrimeTool(const VECTOR2D &aPosition)
"Prime" a tool by sending a cursor left-click event with the mouse position set to the passed in posi...
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
void VetoContextMenuMouseWarp()
Disable mouse warping after the current context menu is closed.
Definition: tool_manager.h:530
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:57
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:190
This file is part of the common library.
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:401
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:536
#define IS_NEW
New item, just created.
#define STRUCT_DELETED
flag indication structures to be erased
#define IS_MOVING
Item being moved.
SHAPE_T
Definition: eda_shape.h:42
FILL_T
Definition: eda_shape.h:55
@ ID_POPUP_SCH_SELECT_UNIT
Definition: eeschema_id.h:82
@ ID_POPUP_SCH_SELECT_BASE
Definition: eeschema_id.h:88
@ ID_POPUP_SCH_SELECT_ALT
Definition: eeschema_id.h:89
@ ID_POPUP_SCH_SELECT_UNIT_END
Definition: eeschema_id.h:86
@ LINE_MODE_FREE
GRID_HELPER_GRIDS
Definition: grid_helper.h:37
@ GRID_TEXT
Definition: grid_helper.h:44
@ GRID_GRAPHICS
Definition: grid_helper.h:45
@ GRID_CONNECTABLE
Definition: grid_helper.h:41
static const std::string KiCadSchematicFileExtension
@ LAYER_HIERLABEL
Definition: layer_ids.h:362
@ LAYER_GLOBLABEL
Definition: layer_ids.h:361
@ LAYER_NOTES
Definition: layer_ids.h:372
@ LAYER_LOCLABEL
Definition: layer_ids.h:360
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:369
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: wxgtk/ui.cpp:611
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
LIB_SYMBOL * SchGetLibSymbol(const LIB_ID &aLibId, SYMBOL_LIB_TABLE *aLibTable, SYMBOL_LIB *aCacheLib, wxWindow *aParent, bool aShowErrorMsg)
Load symbol from symbol library table.
LABEL_FLAG_SHAPE
Definition: sch_label.h:98
@ F_ROUND
Definition: sch_label.h:107
@ L_INPUT
Definition: sch_label.h:99
ANNOTATE_ORDER_T
Schematic annotation order options.
ANNOTATE_ALGO_T
Schematic annotation type options.
@ SHEETNAME
Definition: sch_sheet.h:45
@ SHEETFILENAME
Definition: sch_sheet.h:46
#define MIN_SHEET_HEIGHT
Definition: sch_sheet.h:40
#define MIN_SHEET_WIDTH
Definition: sch_sheet.h:39
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
bool NoPrintableChars(const wxString &aString)
Return true if the string is empty or contains only whitespace.
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
LIB_ID LibId
Definition: sch_screen.h:79
Definition for symbol library class.
constexpr int delta
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
@ TA_CHOICE_MENU_CHOICE
Definition: tool_event.h:97
@ TC_COMMAND
Definition: tool_event.h:56
@ MD_SHIFT
Definition: tool_event.h:142
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_LINE_T
Definition: typeinfo.h:163
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:160
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:161
@ SCH_JUNCTION_T
Definition: typeinfo.h:159
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:100
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:676
Definition of file extensions used in Kicad.