KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_editor_edit_tool.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2019 CERN
5 * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26
27#include <tool/picker_tool.h>
29#include <tools/ee_tool_utils.h>
33#include <clipboard.h>
34#include <ee_actions.h>
35#include <increment.h>
36#include <pin_layout_cache.h>
37#include <string_utils.h>
38#include <symbol_edit_frame.h>
39#include <sch_commit.h>
41#include <dialogs/dialog_text_properties.h>
46#include <view/view_controls.h>
47#include <richio.h>
49#include <sch_textbox.h>
50#include <wx/textdlg.h> // for wxTextEntryDialog
51#include <math/util.h> // for KiROUND
52
54 EE_TOOL_BASE( "eeschema.SymbolEditTool" ),
55 m_pickerItem( nullptr )
56{
57}
58
59
61{
63
66
67 wxASSERT_MSG( drawingTools, "eeschema.SymbolDrawing tool is not available" );
68
69 auto haveSymbolCondition =
70 [&]( const SELECTION& sel )
71 {
73 };
74
75 auto canEdit =
76 [&]( const SELECTION& sel )
77 {
79 return false;
80
81 if( m_frame->IsSymbolAlias() )
82 {
83 for( EDA_ITEM* item : sel )
84 {
85 if( item->Type() != SCH_FIELD_T )
86 return false;
87 }
88 }
89
90 return true;
91 };
92
93 const auto canCopyText = EE_CONDITIONS::OnlyTypes( {
100 } );
101
102 // Add edit actions to the move tool menu
103 if( moveTool )
104 {
105 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
106
107 moveMenu.AddSeparator( 200 );
108 moveMenu.AddItem( EE_ACTIONS::rotateCCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
109 moveMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
110 moveMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::NotEmpty, 200 );
111 moveMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::NotEmpty, 200 );
112
113 moveMenu.AddItem( EE_ACTIONS::swap, canEdit && SELECTION_CONDITIONS::MoreThan( 1 ), 200);
114 moveMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
115
116 moveMenu.AddSeparator( 300 );
119 moveMenu.AddItem( ACTIONS::copyAsText, canCopyText && EE_CONDITIONS::IdleSelection, 300 );
120 moveMenu.AddItem( ACTIONS::duplicate, canEdit && EE_CONDITIONS::NotEmpty, 300 );
121 moveMenu.AddItem( ACTIONS::doDelete, canEdit && EE_CONDITIONS::NotEmpty, 200 );
122
123 moveMenu.AddSeparator( 400 );
124 moveMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
125 moveMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
126 }
127
128 // Add editing actions to the drawing tool menu
129 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
130
131 drawMenu.AddSeparator( 200 );
133 drawMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::IdleSelection, 200 );
134 drawMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::IdleSelection, 200 );
135 drawMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::IdleSelection, 200 );
136
137 drawMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
138
139 // Add editing actions to the selection tool menu
141
142 selToolMenu.AddItem( EE_ACTIONS::rotateCCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
143 selToolMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
144 selToolMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::NotEmpty, 200 );
145 selToolMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::NotEmpty, 200 );
146
147 selToolMenu.AddItem( EE_ACTIONS::swap, canEdit && SELECTION_CONDITIONS::MoreThan( 1 ), 200 );
148 selToolMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
149
150 selToolMenu.AddSeparator( 300 );
153 selToolMenu.AddItem( ACTIONS::copyAsText, canCopyText && EE_CONDITIONS::IdleSelection, 300 );
154 selToolMenu.AddItem( ACTIONS::paste, canEdit && EE_CONDITIONS::Idle, 300 );
155 selToolMenu.AddItem( ACTIONS::duplicate, canEdit && EE_CONDITIONS::NotEmpty, 300 );
156 selToolMenu.AddItem( ACTIONS::doDelete, canEdit && EE_CONDITIONS::NotEmpty, 300 );
157
158 selToolMenu.AddSeparator( 400 );
159 selToolMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
160 selToolMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
161
162 return true;
163}
164
165
167{
169
170 if( selection.GetSize() == 0 )
171 return 0;
172
173 VECTOR2I rotPoint;
174 bool ccw = ( aEvent.Matches( EE_ACTIONS::rotateCCW.MakeEvent() ) );
175 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
176 SCH_COMMIT localCommit( m_toolMgr );
177 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
178
179 if( !commit )
180 commit = &localCommit;
181
182 if( !item->IsMoving() )
183 commit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen() );
184
185 if( selection.GetSize() == 1 )
186 rotPoint = item->GetPosition();
187 else
188 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
189
190 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
191 {
192 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
193 item->Rotate( rotPoint, ccw );
194 m_frame->UpdateItem( item, false, true );
195 }
196
197 if( item->IsMoving() )
198 {
200 }
201 else
202 {
203 if( selection.IsHover() )
205
206 if( !localCommit.Empty() )
207 localCommit.Push( _( "Rotate" ) );
208 }
209
210 return 0;
211}
212
213
215{
217
218 if( selection.GetSize() == 0 )
219 return 0;
220
221 VECTOR2I mirrorPoint;
222 bool xAxis = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
223 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
224
225 if( !item->IsMoving() )
226 saveCopyInUndoList( m_frame->GetCurSymbol(), UNDO_REDO::LIBEDIT );
227
228 if( selection.GetSize() == 1 )
229 {
230 mirrorPoint = item->GetPosition();
231
232 switch( item->Type() )
233 {
234 case SCH_FIELD_T:
235 {
236 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
237
238 if( xAxis )
240 else
242
243 break;
244 }
245
246 default:
247 if( xAxis )
248 item->MirrorVertically( mirrorPoint.y );
249 else
250 item->MirrorHorizontally( mirrorPoint.x );
251
252 break;
253 }
254
255
256 m_frame->UpdateItem( item, false, true );
257 }
258 else
259 {
260 mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
261
262 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
263 {
264 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
265
266 if( xAxis )
267 item->MirrorVertically( mirrorPoint.y );
268 else
269 item->MirrorHorizontally( mirrorPoint.x );
270
271 m_frame->UpdateItem( item, false, true );
272 }
273 }
274
275 if( item->IsMoving() )
276 {
278 }
279 else
280 {
281 if( selection.IsHover() )
283
284 m_frame->OnModify();
285 }
286
287 return 0;
288}
289
290
291const std::vector<KICAD_T> swappableItems = {
292 LIB_SYMBOL_T, // Allows swapping the anchor
293 SCH_PIN_T,
298};
299
300
302{
304 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
305
306 if( selection.Size() < 2 )
307 return 0;
308
309 EDA_ITEM* front = selection.Front();
310 bool isMoving = front->IsMoving();
311
312 // Save copy for undo if not in edit (edit command already handle the save copy)
313 if( front->GetEditFlags() == 0 )
314 saveCopyInUndoList( front->GetParent(), UNDO_REDO::LIBEDIT );
315
316 for( size_t i = 0; i < sorted.size() - 1; i++ )
317 {
318 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
319 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
320
321 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
322 std::swap( aPos, bPos );
323
324 a->SetPosition( aPos );
325 b->SetPosition( bPos );
326
327 // Special case some common swaps
328 if( a->Type() == b->Type() )
329 {
330 switch( a->Type() )
331 {
332 case SCH_PIN_T:
333 {
334 SCH_PIN* aPin = static_cast<SCH_PIN*>( a );
335 SCH_PIN* bBpin = static_cast<SCH_PIN*>( b );
336
337 PIN_ORIENTATION aOrient = aPin->GetOrientation();
338 PIN_ORIENTATION bOrient = bBpin->GetOrientation();
339
340 aPin->SetOrientation( bOrient );
341 bBpin->SetOrientation( aOrient );
342
343 break;
344 }
345 default: break;
346 }
347 }
348
349 m_frame->UpdateItem( a, false, true );
350 m_frame->UpdateItem( b, false, true );
351 }
352
353 // Update R-Tree for modified items
354 for( EDA_ITEM* selected : selection )
355 updateItem( selected, true );
356
357 if( isMoving )
358 {
360 }
361 else
362 {
363 if( selection.IsHover() )
365
366 m_frame->OnModify();
367 }
368
369 return 0;
370}
371
372
373static std::vector<KICAD_T> nonFields =
374{
380};
381
382
384{
385 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
386 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection().GetItems();
387 SCH_COMMIT commit( m_frame );
388
389 if( items.empty() )
390 return 0;
391
392 // Don't leave a freed pointer in the selection
394
395 commit.Modify( symbol, m_frame->GetScreen() );
396
397 std::set<SCH_ITEM*> toDelete;
398 int fieldsHidden = 0;
399 int fieldsAlreadyHidden = 0;
400
401 for( EDA_ITEM* item : items )
402 {
403 if( item->Type() == SCH_PIN_T )
404 {
405 SCH_PIN* curr_pin = static_cast<SCH_PIN*>( item );
406 VECTOR2I pos = curr_pin->GetPosition();
407
408 toDelete.insert( curr_pin );
409
410 // when pin editing is synchronized, pins in the same position, with the same name
411 // in different units are also removed. But only one pin per unit (matching)
412 if( m_frame->SynchronizePins() )
413 {
414 std::vector<bool> got_unit( symbol->GetUnitCount() + 1 );
415
416 got_unit[curr_pin->GetUnit()] = true;
417
418 for( SCH_PIN* pin : symbol->GetAllLibPins() )
419 {
420 if( got_unit[pin->GetUnit()] )
421 continue;
422
423 if( pin->GetPosition() != pos )
424 continue;
425
426 if( pin->GetBodyStyle() != curr_pin->GetBodyStyle() )
427 continue;
428
429 if( pin->GetType() != curr_pin->GetType() )
430 continue;
431
432 if( pin->GetName() != curr_pin->GetName() )
433 continue;
434
435 toDelete.insert( pin );
436 got_unit[pin->GetUnit()] = true;
437 }
438 }
439 }
440 else if( item->Type() == SCH_FIELD_T )
441 {
442 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
443
444 // Hide "deleted" fields
445 if( field->IsVisible() )
446 {
447 field->SetVisible( false );
448 fieldsHidden++;
449 }
450 else
451 {
452 fieldsAlreadyHidden++;
453 }
454 }
455 else if( SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item ) )
456 {
457 toDelete.insert( schItem );
458 }
459 }
460
461 for( SCH_ITEM* item : toDelete )
462 symbol->RemoveDrawItem( item );
463
464 if( toDelete.size() == 0 )
465 {
466 if( fieldsHidden == 1 )
467 commit.Push( _( "Hide Field" ) );
468 else if( fieldsHidden > 1 )
469 commit.Push( _( "Hide Fields" ) );
470 else if( fieldsAlreadyHidden > 0 )
471 m_frame->ShowInfoBarError( _( "Use the Symbol Properties dialog to remove fields." ) );
472 }
473 else
474 {
475 commit.Push( _( "Delete" ) );
476 }
477
479 return 0;
480}
481
482
483#define HITTEST_THRESHOLD_PIXELS 5
484
485
487{
489
491 m_pickerItem = nullptr;
492
493 // Deactivate other tools; particularly important if another PICKER is currently running
494 Activate();
495
496 picker->SetCursor( KICURSOR::REMOVE );
497
498 picker->SetClickHandler(
499 [this]( const VECTOR2D& aPosition ) -> bool
500 {
501 if( m_pickerItem )
502 {
504 selectionTool->UnbrightenItem( m_pickerItem );
505 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
507 m_pickerItem = nullptr;
508 }
509
510 return true;
511 } );
512
513 picker->SetMotionHandler(
514 [this]( const VECTOR2D& aPos )
515 {
517 EE_COLLECTOR collector;
518
519 selectionTool->CollectHits( collector, aPos, nonFields );
520
521 // Remove unselectable items
522 for( int i = collector.GetCount() - 1; i >= 0; --i )
523 {
524 if( !selectionTool->Selectable( collector[ i ] ) )
525 collector.Remove( i );
526 }
527
528 if( collector.GetCount() > 1 )
529 selectionTool->GuessSelectionCandidates( collector, aPos );
530
531 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
532
533 if( m_pickerItem != item )
534 {
535 if( m_pickerItem )
536 selectionTool->UnbrightenItem( m_pickerItem );
537
538 m_pickerItem = item;
539
540 if( m_pickerItem )
541 selectionTool->BrightenItem( m_pickerItem );
542 }
543 } );
544
545 picker->SetFinalizeHandler(
546 [this]( const int& aFinalState )
547 {
548 if( m_pickerItem )
549 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
550
551 // Wake the selection tool after exiting to ensure the cursor gets updated
553 } );
554
556
557 return 0;
558}
559
560
562{
564
565 if( selection.Empty() || aEvent.IsAction( &EE_ACTIONS::symbolProperties ) )
566 {
567 if( m_frame->GetCurSymbol() )
569 }
570 else if( selection.Size() == 1 )
571 {
572 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
573
574 // Save copy for undo if not in edit (edit command already handle the save copy)
575 if( item->GetEditFlags() == 0 )
576 saveCopyInUndoList( item->GetParent(), UNDO_REDO::LIBEDIT );
577
578 switch( item->Type() )
579 {
580 case SCH_PIN_T:
581 {
582 SCH_PIN& pin = static_cast<SCH_PIN&>( *item );
583
584 // Mouse, not cursor, as grid points may well not be under any text
585 const VECTOR2I& mousePos = m_toolMgr->GetMousePosition();
586 PIN_LAYOUT_CACHE& layout = pin.GetLayoutCache();
587
588 bool mouseOverNumber = false;
589 if( OPT_BOX2I numberBox = layout.GetPinNumberBBox() )
590 {
591 mouseOverNumber = numberBox->Contains( mousePos );
592 }
593
595 pinTool->EditPinProperties( &pin, mouseOverNumber );
596
597 break;
598 }
599 case SCH_SHAPE_T:
600 editShapeProperties( static_cast<SCH_SHAPE*>( item ) );
601 break;
602
603 case SCH_TEXT_T:
604 editTextProperties( item );
605 break;
606
607 case SCH_TEXTBOX_T:
608 editTextBoxProperties( item );
609 break;
610
611 case SCH_FIELD_T:
612 editFieldProperties( static_cast<SCH_FIELD*>( item ) );
613 break;
614
615 default:
616 wxFAIL_MSG( wxT( "Unhandled item <" ) + item->GetClass() + wxT( ">" ) );
617 break;
618 }
619 }
620
621 if( selection.IsHover() )
623
624 return 0;
625}
626
627
629{
630 DIALOG_SHAPE_PROPERTIES dlg( m_frame, aShape );
631
632 if( dlg.ShowModal() != wxID_OK )
633 return;
634
635 updateItem( aShape, true );
637 m_frame->OnModify();
638
641 drawingTools->SetDrawSpecificUnit( !dlg.GetApplyToAllUnits() );
642
643 std::vector<MSG_PANEL_ITEM> items;
644 aShape->GetMsgPanelInfo( m_frame, items );
645 m_frame->SetMsgPanel( items );
646}
647
648
650{
651 if ( aItem->Type() != SCH_TEXT_T )
652 return;
653
654 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_TEXT*>( aItem ) );
655
656 if( dlg.ShowModal() != wxID_OK )
657 return;
658
659 updateItem( aItem, true );
661 m_frame->OnModify( );
662}
663
664
666{
667 if ( aItem->Type() != SCH_TEXTBOX_T )
668 return;
669
670 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_TEXTBOX*>( aItem ) );
671
672 if( dlg.ShowModal() != wxID_OK )
673 return;
674
675 updateItem( aItem, true );
677 m_frame->OnModify( );
678}
679
680
682{
683 if( aField == nullptr )
684 return;
685
686 wxString caption;
687
688 if( aField->IsMandatory() )
689 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
690 else
691 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
692
693 DIALOG_FIELD_PROPERTIES dlg( m_frame, caption, aField );
694
695 // The dialog may invoke a kiway player for footprint fields
696 // so we must use a quasimodal dialog.
697 if( dlg.ShowQuasiModal() != wxID_OK )
698 return;
699
700 wxString newFieldValue = EscapeString( dlg.GetText(), CTX_LIBID );
701 wxString oldFieldValue = aField->GetFullText( m_frame->GetUnit() );
702
703 SCH_COMMIT commit( m_toolMgr );
704 commit.Modify( aField, m_frame->GetScreen() );
705
706 dlg.UpdateField( aField );
707
708 commit.Push( caption );
709
712}
713
714
716{
717 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
718 bool partLocked = symbol->UnitsLocked();
719
722
724
725 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
726 // frame. Therefore this dialog as a modal frame parent, MUST be run under
727 // quasimodal mode for the quasimodal frame support to work. So don't use
728 // the QUASIMODAL macros here.
729 if( dlg.ShowQuasiModal() != wxID_OK )
730 return;
731
732 m_frame->OnModify();
733
734 // if m_UnitSelectionLocked has changed, set some edit options or defaults
735 // to the best value
736 if( partLocked != symbol->UnitsLocked() )
737 {
739
740 // Enable synchronized pin edit mode for symbols with interchangeable units
741 m_frame->m_SyncPinEdit = !symbol->UnitsLocked();
742
743 // also set default edit options to the better value
744 // Usually if units are locked, graphic items are specific to each unit
745 // and if units are interchangeable, graphic items are common to units
746 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
747 }
748}
749
751 int& aSymbolLastPinNumber )
752{
753 if( !aNewPin->GetNumber().IsEmpty() )
754 {
755 // when duplicating a pin in symbol editor, assigning identical pin number
756 // to the old one does not makes any sense, so assign the next unassigned number to it
757 aSymbolLastPinNumber++;
758 aNewPin->SetNumber( wxString::Format( wxT( "%i" ), aSymbolLastPinNumber ) );
759 }
760}
761
763{
764 SCH_COMMIT commit( m_frame );
765 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
766
767 if( !symbol )
768 return 0;
769
770 commit.Modify( symbol );
771
773
774 DIALOG_LIB_EDIT_PIN_TABLE dlg( m_frame, symbol );
775
776 if( dlg.ShowModal() == wxID_CANCEL )
777 return -1;
778
779 commit.Push( _( "Edit Pins" ) );
781
782 return 0;
783}
784
785
787{
788 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
789
790 if( !symbol )
791 return 0;
792
793 if( !symbol->IsAlias() )
794 {
795 m_frame->ShowInfoBarError( _( "Symbol is not derived from another symbol." ) );
796 }
797 else
798 {
800
801 if( dlg.ShowModal() == wxID_CANCEL )
802 return -1;
803 }
804
805 return 0;
806}
807
808
810{
811 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
812
813 if( !symbol )
814 return 0;
815
816 int unitid = m_frame->GetUnit();
817
818 if( unitid == 0 )
819 {
820 return -1;
821 }
822
823 wxString promptText = wxString::Format( _( "Enter display name for unit %s" ),
824 symbol->GetUnitReference( unitid ) );
825 wxString currentvalue;
826
827 if( symbol->HasUnitDisplayName( unitid ) )
828 {
829 currentvalue = symbol->GetUnitDisplayName( unitid );
830 }
831
832 wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue );
833
834 if( dlg.ShowModal() == wxID_OK )
835 {
836 saveCopyInUndoList( symbol, UNDO_REDO::LIBEDIT );
837 symbol->SetUnitDisplayName( unitid, dlg.GetValue() );
839 m_frame->OnModify();
840 }
841 else
842 {
843 return -1;
844 }
845
846 return 0;
847}
848
849
851{
853
854 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
855 // it just clears the SELECTION's reference to them.
856 selTool->GetSelection().Clear();
857 {
859 }
860 selTool->RebuildSelection();
861
862 return 0;
863}
864
865
867{
869
870 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
871 // it just clears the SELECTION's reference to them.
872 selTool->GetSelection().Clear();
873 {
875 }
876 selTool->RebuildSelection();
877
878 return 0;
879}
880
881
883{
884 int retVal = Copy( aEvent );
885
886 if( retVal == 0 )
887 retVal = DoDelete( aEvent );
888
889 return retVal;
890}
891
892
894{
895 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
897
898 if( !symbol || !selection.GetSize() )
899 return 0;
900
901 for( SCH_ITEM& item : symbol->GetDrawItems() )
902 {
903 if( item.Type() == SCH_FIELD_T )
904 continue;
905
906 wxASSERT( !item.HasFlag( STRUCT_DELETED ) );
907
908 if( !item.IsSelected() )
909 item.SetFlags( STRUCT_DELETED );
910 }
911
912 LIB_SYMBOL* partCopy = new LIB_SYMBOL( *symbol );
913
914 STRING_FORMATTER formatter;
915 SCH_IO_KICAD_SEXPR::FormatLibSymbol( partCopy, formatter );
916
917 delete partCopy;
918
919 for( SCH_ITEM& item : symbol->GetDrawItems() )
921
922 if( SaveClipboard( formatter.GetString() ) )
923 return 0;
924 else
925 return -1;
926}
927
928
930{
932 EE_SELECTION& selection = selTool->RequestSelection();
933
934 if( selection.Empty() )
935 return 0;
936
937 wxString itemsAsText = GetSelectedItemsAsText( selection );
938
939 if( selection.IsHover() )
941
942 return SaveClipboard( itemsAsText.ToStdString() );
943}
944
945
947{
948 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
949 LIB_SYMBOL* newPart = nullptr;
950
951 if( !symbol || symbol->IsAlias() )
952 return 0;
953
954 std::string clipboardData = GetClipboardUTF8();
955
956 try
957 {
958 std::vector<LIB_SYMBOL*> newParts = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
959
960 if( newParts.empty() || !newParts[0] )
961 return -1;
962
963 newPart = newParts[0];
964 }
965 catch( IO_ERROR& )
966 {
967 // If it's not a symbol then paste as text
968 newPart = new LIB_SYMBOL( "dummy_part" );
969 SCH_TEXT* newText = new SCH_TEXT( { 0, 0 }, clipboardData, LAYER_DEVICE );
970 newPart->AddDrawItem( newText );
971 }
972
973 SCH_COMMIT commit( m_toolMgr );
974
975 commit.Modify( symbol );
977
978 for( SCH_ITEM& item : symbol->GetDrawItems() )
979 item.ClearFlags( IS_NEW | IS_PASTED | SELECTED );
980
981 for( SCH_ITEM& item : newPart->GetDrawItems() )
982 {
983 if( item.Type() == SCH_FIELD_T )
984 continue;
985
986 SCH_ITEM* newItem = item.Duplicate();
987 newItem->SetParent( symbol );
988 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
989
990 newItem->SetUnit( newItem->GetUnit() ? m_frame->GetUnit() : 0 );
991 newItem->SetBodyStyle( newItem->GetBodyStyle() ? m_frame->GetBodyStyle() : 0 );
992
993 symbol->AddDrawItem( newItem );
994 getView()->Add( newItem );
995 }
996
997 delete newPart;
998
1000
1002
1003 if( !selection.Empty() )
1004 {
1005 selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
1006
1008 commit.Push( _( "Paste" ) );
1009 else
1010 commit.Revert();
1011 }
1012
1013 return 0;
1014}
1015
1016
1018{
1019 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
1021 SCH_COMMIT commit( m_toolMgr );
1022
1023 if( selection.GetSize() == 0 )
1024 return 0;
1025
1026 commit.Modify( symbol, m_frame->GetScreen() );
1027
1028 std::vector<EDA_ITEM*> oldItems;
1029 std::vector<EDA_ITEM*> newItems;
1030
1031 std::copy( selection.begin(), selection.end(), std::back_inserter( oldItems ) );
1032 std::sort( oldItems.begin(), oldItems.end(), []( EDA_ITEM* a, EDA_ITEM* b )
1033 {
1034 int cmp;
1035
1036 if( a->Type() != b->Type() )
1037 return a->Type() < b->Type();
1038
1039 // Create the new pins in the same order as the old pins
1040 if( a->Type() == SCH_PIN_T )
1041 {
1042 const wxString& aNum = static_cast<SCH_PIN*>( a )->GetNumber();
1043 const wxString& bNum = static_cast<SCH_PIN*>( b )->GetNumber();
1044
1045 cmp = StrNumCmp( aNum, bNum );
1046
1047 // If the pin numbers are not numeric, then just number them by their position
1048 // on the screen.
1049 if( aNum.IsNumber() && bNum.IsNumber() && cmp != 0 )
1050 return cmp < 0;
1051 }
1052
1054
1055 if( cmp != 0 )
1056 return cmp < 0;
1057
1058 return a->m_Uuid < b->m_Uuid;
1059 } );
1060
1061 for( EDA_ITEM* item : oldItems )
1062 {
1063 SCH_ITEM* oldItem = static_cast<SCH_ITEM*>( item );
1064 SCH_ITEM* newItem = oldItem->Duplicate();
1065
1066 if( newItem->Type() == SCH_PIN_T )
1067 {
1068 SCH_PIN* newPin = static_cast<SCH_PIN*>( newItem );
1069
1070 if( !newPin->GetNumber().IsEmpty() )
1071 newPin->SetNumber( wxString::Format( wxT( "%i" ), symbol->GetMaxPinNumber() + 1 ) );
1072 }
1073
1074 oldItem->ClearFlags( IS_NEW | IS_PASTED | SELECTED );
1075 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
1076 newItem->SetParent( symbol );
1077 newItems.push_back( newItem );
1078
1079 symbol->AddDrawItem( newItem );
1080 getView()->Add( newItem );
1081 }
1082
1083 m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
1084 m_toolMgr->RunAction<EDA_ITEMS*>( EE_ACTIONS::addItemsToSel, &newItems );
1085
1086 selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
1087
1088 if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit ) )
1089 commit.Push( _( "Duplicate" ) );
1090 else
1091 commit.Revert();
1092
1093 return 0;
1094}
1095
1096
1098{
1099 const ACTIONS::INCREMENT incParam = aEvent.Parameter<ACTIONS::INCREMENT>();
1101
1102 if( selection.Empty() )
1103 return 0;
1104
1105 KICAD_T type = selection.Front()->Type();
1106 bool allSameType = true;
1107 for( EDA_ITEM* item : selection )
1108 {
1109 if( item->Type() != type )
1110 {
1111 allSameType = false;
1112 break;
1113 }
1114 }
1115
1116 // Incrementing multiple types at once seems confusing
1117 // though it would work.
1118 if( !allSameType )
1119 return 0;
1120
1121 const VECTOR2I mousePosition = getViewControls()->GetMousePosition();
1122
1123 STRING_INCREMENTER incrementer;
1124 incrementer.SetSkipIOSQXZ( true );
1125
1126 SCH_COMMIT commit( m_frame );
1127
1128 for( EDA_ITEM* item : selection )
1129 {
1130 switch( item->Type() )
1131 {
1132 case SCH_PIN_T:
1133 {
1134 SCH_PIN& pin = static_cast<SCH_PIN&>( *item );
1135 PIN_LAYOUT_CACHE& layout = pin.GetLayoutCache();
1136
1137 bool found = false;
1138 OPT_BOX2I bbox = layout.GetPinNumberBBox();
1139
1140 if( bbox && bbox->Contains( mousePosition ) )
1141 {
1142 std::optional<wxString> nextNumber =
1143 incrementer.Increment( pin.GetNumber(), incParam.Delta, incParam.Index );
1144 if( nextNumber )
1145 {
1146 commit.Modify( &pin );
1147 pin.SetNumber( *nextNumber );
1148 }
1149 found = true;
1150 }
1151
1152 if( !found )
1153 {
1154 bbox = layout.GetPinNameBBox();
1155
1156 if( bbox && bbox->Contains( mousePosition ) )
1157 {
1158 std::optional<wxString> nextName =
1159 incrementer.Increment( pin.GetName(), incParam.Delta, incParam.Index );
1160 if( nextName )
1161 {
1162 commit.Modify( &pin );
1163 pin.SetName( *nextName );
1164 }
1165 found = true;
1166 }
1167 }
1168 break;
1169 }
1170 case SCH_TEXT_T:
1171 {
1172 SCH_TEXT& label = static_cast<SCH_TEXT&>( *item );
1173
1174 std::optional<wxString> newLabel =
1175 incrementer.Increment( label.GetText(), incParam.Delta, incParam.Index );
1176 if( newLabel )
1177 {
1178 commit.Modify( &label, m_frame->GetScreen() );
1179 label.SetText( *newLabel );
1180 }
1181 break;
1182 }
1183 default:
1184 // No increment for other items
1185 break;
1186 }
1187 }
1188
1189 commit.Push( _( "Increment" ) );
1190
1191 return 0;
1192}
1193
1194
1196{
1197 // clang-format off
1205
1213
1219
1225 // clang-format on
1226}
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:926
static TOOL_ACTION decrementPrimary
Definition: actions.h:89
static TOOL_ACTION paste
Definition: actions.h:73
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static TOOL_ACTION unselectAll
Definition: actions.h:76
static TOOL_ACTION decrementSecondary
Definition: actions.h:91
static TOOL_ACTION copy
Definition: actions.h:71
static TOOL_ACTION pickerTool
Definition: actions.h:204
static TOOL_ACTION undo
Definition: actions.h:68
static TOOL_ACTION incrementSecondary
Definition: actions.h:90
static TOOL_ACTION duplicate
Definition: actions.h:77
static TOOL_ACTION incrementPrimary
Definition: actions.h:88
static TOOL_ACTION doDelete
Definition: actions.h:78
static TOOL_ACTION redo
Definition: actions.h:69
static TOOL_ACTION deleteTool
Definition: actions.h:79
static TOOL_ACTION increment
Definition: actions.h:87
static TOOL_ACTION cut
Definition: actions.h:70
static TOOL_ACTION copyAsText
Definition: actions.h:72
static TOOL_ACTION refreshPreview
Definition: actions.h:149
static TOOL_ACTION selectAll
Definition: actions.h:75
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
bool Empty() const
Returns status of an item.
Definition: commit.h:144
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.
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
This class is setup in expectation of its children possibly using Kiway player so DIALOG_SHIM::ShowQu...
void UpdateField(SCH_FIELD *aField)
const wxString & GetText() const
int ShowQuasiModal()
int ShowModal() override
Dialog to update or change schematic library symbols.
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...
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
VECTOR2I GetNearestHalfGridPosition(const VECTOR2I &aPosition) const
Return the nearest aGridSize / 2 location to aPosition.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:243
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:244
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 void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
bool IsMoving() const
Definition: eda_item.h:108
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
virtual bool IsVisible() const
Definition: eda_text.h:170
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:321
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:183
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:290
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:186
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:182
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:313
static TOOL_ACTION mirrorV
Definition: ee_actions.h:132
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
static TOOL_ACTION properties
Definition: ee_actions.h:135
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: ee_actions.h:63
static TOOL_ACTION move
Definition: ee_actions.h:127
static TOOL_ACTION pinTable
Definition: ee_actions.h:162
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:131
static TOOL_ACTION mirrorH
Definition: ee_actions.h:133
static TOOL_ACTION rotateCW
Definition: ee_actions.h:130
static TOOL_ACTION symbolProperties
Definition: ee_actions.h:161
static TOOL_ACTION setUnitDisplayName
Definition: ee_actions.h:228
static TOOL_ACTION updateSymbolFields
Definition: ee_actions.h:227
static TOOL_ACTION swap
Definition: ee_actions.h:134
bool Selectable(const EDA_ITEM *aItem, const VECTOR2I *aPos=nullptr, bool checkVisibilityOnly=false) const
Check conditions for an item to be selected.
void GuessSelectionCandidates(EE_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
bool CollectHits(EE_COLLECTOR &aCollector, const VECTOR2I &aWhere, const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T })
Collect one or more items at a given point.
EE_SELECTION & RequestSelection(const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, bool aPromoteCellSelections=false)
Return either an existing selection (filtered), or the selection at the current cursor position if th...
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
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
void saveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aType, bool aAppend=false, bool aDirtyConnectivity=true)
Definition: ee_tool_base.h:143
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
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:317
Define a library symbol object.
Definition: lib_symbol.h:78
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:264
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:260
bool IsAlias() const
Definition: lib_symbol.h:195
std::vector< SCH_PIN * > GetAllLibPins() const
Return a list of pin pointers for all units / converts.
Definition: lib_symbol.cpp:842
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:499
void RemoveDrawItem(SCH_ITEM *aItem)
Remove draw aItem from list.
Definition: lib_symbol.cpp:771
bool HasUnitDisplayName(int aUnit) override
Return true if the given unit aUnit has a display name defined.
Definition: lib_symbol.cpp:254
wxString GetUnitReference(int aUnit) override
Return an identifier for aUnit for symbols with units.
Definition: lib_symbol.cpp:248
int GetUnitCount() const override
void SetUnitDisplayName(int aUnit, const wxString &aName)
Set the user-defined display name for aUnit to aName for symbols with units.
Definition: lib_symbol.cpp:276
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:796
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:84
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:73
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:64
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:104
A pin layout helper is a class that manages the layout of the parts of a pin on a schematic symbol:
OPT_BOX2I GetPinNumberBBox()
Get the bounding box of the pin number, if there is one.
OPT_BOX2I GetPinNameBBox()
Get the bounding box of the pin name, if there is one.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
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:432
virtual void Revert() override
Definition: sch_commit.cpp:510
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
bool IsMandatory() const
Definition: sch_field.cpp:1507
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: sch_field.cpp:335
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1227
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
virtual void SetBodyStyle(int aBodyStyle)
Definition: sch_item.h:231
int GetBodyStyle() const
Definition: sch_item.h:232
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
Definition: sch_item.h:343
int GetUnit() const
Definition: sch_item.h:229
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_item.h:359
virtual void SetUnit(int aUnit)
Definition: sch_item.h:228
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:176
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:131
virtual void MirrorVertically(int aCenter)
Mirror item vertically about aCenter.
Definition: sch_item.h:351
void SetNumber(const wxString &aNumber)
Definition: sch_pin.cpp:514
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: sch_pin.h:86
const wxString & GetName() const
Definition: sch_pin.cpp:375
PIN_ORIENTATION GetOrientation() const
Definition: sch_pin.cpp:258
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:250
const wxString & GetNumber() const
Definition: sch_pin.h:117
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:304
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: sch_shape.cpp:499
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
void BrightenItem(EDA_ITEM *aItem)
int AddItemToSel(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:75
ITER end()
Definition: selection.h:75
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:121
ITER begin()
Definition: selection.h:74
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:93
bool IsHover() const
Definition: selection.h:84
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
std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:265
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:180
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:436
const std::string & GetString()
Definition: richio.h:459
Heuristically increment a string's n'th part from the right.
Definition: increment.h:48
void SetSkipIOSQXZ(bool aSkip)
If a alphabetic part is found, skip the letters I, O, S, Q, X, Z.
Definition: increment.h:54
std::optional< wxString > Increment(const wxString &aStr, int aDelta, size_t aRightIndex) const
Increment the n-th part from the right of the given string.
Definition: increment.cpp:85
SYMBOL_EDITOR_DRAWING_TOOLS.
void SetDrawSpecificBodyStyle(bool aSpecific)
int Undo(const TOOL_EVENT &aEvent)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void editTextBoxProperties(SCH_ITEM *aItem)
int PinTable(const TOOL_EVENT &aEvent)
int Increment(const TOOL_EVENT &aEvent)
int Copy(const TOOL_EVENT &aEvent)
int CopyAsText(const TOOL_EVENT &aEvent)
int Paste(const TOOL_EVENT &aEvent)
int Cut(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
int Redo(const TOOL_EVENT &aEvent)
void editTextProperties(SCH_ITEM *aItem)
int Swap(const TOOL_EVENT &aEvent)
void editFieldProperties(SCH_FIELD *aField)
void handlePinDuplication(SCH_PIN *aOldPin, SCH_PIN *aNewPin, int &aSymbolLastPinNumber)
Set up handlers for various events.
void editShapeProperties(SCH_SHAPE *aShape)
int Duplicate(const TOOL_EVENT &aEvent)
int Mirror(const TOOL_EVENT &aEvent)
int InteractiveDelete(const TOOL_EVENT &aEvent)
int Rotate(const TOOL_EVENT &aEvent)
int Properties(const TOOL_EVENT &aEvent)
int SetUnitDisplayName(const TOOL_EVENT &aEvent)
int UpdateSymbolFields(const TOOL_EVENT &aEvent)
int DoDelete(const TOOL_EVENT &aEvent)
Delete the selected items, or the item under the cursor.
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
bool IsSymbolAlias() const
Return true if aLibId is an alias for the editor screen symbol.
int GetBodyStyle() const
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
bool IsSymbolEditable() const
Test if a symbol is loaded and can be edited.
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
void UpdateSymbolMsgPanelInfo()
Display the documentation of the selected symbol.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
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 Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:384
COMMIT * Commit() const
Returns information about difference between current mouse cursor position and the place where draggi...
Definition: tool_event.h:275
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 & GetToolMenu()
void Activate()
Run the 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
VECTOR2D GetMousePosition() const
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:197
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
Definition: clipboard.cpp:31
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:51
#define _(s)
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:536
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
#define IS_NEW
New item, just created.
#define SELECTED
Item was manually selected by the user.
#define STRUCT_DELETED
flag indication structures to be erased
wxString GetSelectedItemsAsText(const SELECTION &aSel)
@ LAYER_DEVICE
Definition: layer_ids.h:370
PIN_ORIENTATION
The symbol library pin object orientations.
Definition: pin_type.h:78
const std::vector< KICAD_T > swappableItems
wxString TitleCaps(const wxString &aString)
Capitalize the first letter in each word.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
Definition: string_utils.h:54
static std::vector< KICAD_T > nonFields
const std::vector< KICAD_T > swappableItems
constexpr GR_TEXT_H_ALIGN_T GetFlippedAlignment(GR_TEXT_H_ALIGN_T aAlign)
Get the reverse alignment: left-right are swapped, others are unchanged.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_TABLE_T
Definition: typeinfo.h:165
@ LIB_SYMBOL_T
Definition: typeinfo.h:148
@ SCH_TABLECELL_T
Definition: typeinfo.h:166
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_TEXT_T
Definition: typeinfo.h:151
@ SCH_TEXTBOX_T
Definition: typeinfo.h:152
@ SCH_PIN_T
Definition: typeinfo.h:153
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:640