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
25#include <tool/picker_tool.h>
30#include <ee_actions.h>
31#include <string_utils.h>
32#include <symbol_edit_frame.h>
33#include <sch_commit.h>
42#include <lib_text.h>
43#include <lib_textbox.h>
45#include <wx/textdlg.h> // for wxTextEntryDialog
46#include <math/util.h> // for KiROUND
47
49 EE_TOOL_BASE( "eeschema.SymbolEditTool" ),
50 m_pickerItem( nullptr )
51{
52}
53
54
56{
58
61
62 wxASSERT_MSG( drawingTools, "eeschema.SymbolDrawing tool is not available" );
63
64 auto haveSymbolCondition =
65 [&]( const SELECTION& sel )
66 {
67 return m_isSymbolEditor &&
68 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->GetCurSymbol();
69 };
70
71 auto canEdit =
72 [&]( const SELECTION& sel )
73 {
75 wxCHECK( editor, false );
76
77 if( !editor->IsSymbolEditable() )
78 return false;
79
80 if( editor->IsSymbolAlias() )
81 {
82 for( EDA_ITEM* item : sel )
83 {
84 if( item->Type() != LIB_FIELD_T )
85 return false;
86 }
87 }
88
89 return true;
90 };
91
92 // Add edit actions to the move tool menu
93 if( moveTool )
94 {
95 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
96
97 moveMenu.AddSeparator( 200 );
98 moveMenu.AddItem( EE_ACTIONS::rotateCCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
99 moveMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
100 moveMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::NotEmpty, 200 );
101 moveMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::NotEmpty, 200 );
102
103 moveMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
104
105 moveMenu.AddSeparator( 300 );
108 moveMenu.AddItem( ACTIONS::duplicate, canEdit && EE_CONDITIONS::NotEmpty, 300 );
109 moveMenu.AddItem( ACTIONS::doDelete, canEdit && EE_CONDITIONS::NotEmpty, 200 );
110
111 moveMenu.AddSeparator( 400 );
112 moveMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
113 moveMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
114 }
115
116 // Add editing actions to the drawing tool menu
117 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
118
119 drawMenu.AddSeparator( 200 );
121 drawMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::IdleSelection, 200 );
122 drawMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::IdleSelection, 200 );
123 drawMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::IdleSelection, 200 );
124
125 drawMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
126
127 // Add editing actions to the selection tool menu
129
130 selToolMenu.AddItem( EE_ACTIONS::rotateCCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
131 selToolMenu.AddItem( EE_ACTIONS::rotateCW, canEdit && EE_CONDITIONS::NotEmpty, 200 );
132 selToolMenu.AddItem( EE_ACTIONS::mirrorV, canEdit && EE_CONDITIONS::NotEmpty, 200 );
133 selToolMenu.AddItem( EE_ACTIONS::mirrorH, canEdit && EE_CONDITIONS::NotEmpty, 200 );
134
135 selToolMenu.AddItem( EE_ACTIONS::properties, canEdit && EE_CONDITIONS::Count( 1 ), 200 );
136
137 selToolMenu.AddSeparator( 300 );
140 selToolMenu.AddItem( ACTIONS::paste, canEdit && EE_CONDITIONS::Idle, 300 );
141 selToolMenu.AddItem( ACTIONS::duplicate, canEdit && EE_CONDITIONS::NotEmpty, 300 );
142 selToolMenu.AddItem( ACTIONS::doDelete, canEdit && EE_CONDITIONS::NotEmpty, 300 );
143
144 selToolMenu.AddSeparator( 400 );
145 selToolMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
146 selToolMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
147
148 return true;
149}
150
151
153{
155
156 if( selection.GetSize() == 0 )
157 return 0;
158
159 VECTOR2I rotPoint;
160 bool ccw = ( aEvent.Matches( EE_ACTIONS::rotateCCW.MakeEvent() ) );
161 LIB_ITEM* item = static_cast<LIB_ITEM*>( selection.Front() );
162 SCH_COMMIT localCommit( m_toolMgr );
163 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
164
165 if( !commit )
166 commit = &localCommit;
167
168 if( !item->IsMoving() )
169 commit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen() );
170
171 if( selection.GetSize() == 1 )
172 rotPoint = item->GetPosition();
173 else
174 rotPoint = m_frame->GetNearestHalfGridPosition( mapCoords( selection.GetCenter() ) );
175
176 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
177 {
178 item = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
179 item->Rotate( rotPoint, ccw );
180 m_frame->UpdateItem( item, false, true );
181 }
182
183 if( item->IsMoving() )
184 {
186 }
187 else
188 {
189
190 if( selection.IsHover() )
192
193 if( !localCommit.Empty() )
194 localCommit.Push( _( "Rotate" ) );
195 }
196
197 return 0;
198}
199
200
202{
204
205 if( selection.GetSize() == 0 )
206 return 0;
207
208 VECTOR2I mirrorPoint;
209 bool xAxis = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
210 LIB_ITEM* item = static_cast<LIB_ITEM*>( selection.Front() );
211
212 if( !item->IsMoving() )
213 saveCopyInUndoList( m_frame->GetCurSymbol(), UNDO_REDO::LIBEDIT );
214
215 if( selection.GetSize() == 1 )
216 {
217 mirrorPoint = item->GetPosition();
218
219 switch( item->Type() )
220 {
221 case LIB_FIELD_T:
222 {
223 LIB_FIELD* field = static_cast<LIB_FIELD*>( item );
224
225 if( xAxis )
226 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
227 else
228 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
229
230 break;
231 }
232
233 default:
234 if( xAxis )
235 item->MirrorVertical( mirrorPoint );
236 else
237 item->MirrorHorizontal( mirrorPoint );
238
239 break;
240 }
241
242
243 m_frame->UpdateItem( item, false, true );
244 }
245 else
246 {
247 mirrorPoint = m_frame->GetNearestHalfGridPosition( mapCoords( selection.GetCenter() ) );
248
249 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
250 {
251 item = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
252
253 if( xAxis )
254 item->MirrorVertical( mirrorPoint );
255 else
256 item->MirrorHorizontal( mirrorPoint );
257
258 m_frame->UpdateItem( item, false, true );
259 }
260 }
261
262 if( item->IsMoving() )
263 {
265 }
266 else
267 {
268 if( selection.IsHover() )
270
271 m_frame->OnModify();
272 }
273
274 return 0;
275}
276
277
278static std::vector<KICAD_T> nonFields =
279{
285};
286
287
289{
290 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
291 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection( nonFields ).GetItems();
292 SCH_COMMIT commit( m_frame );
293
294 if( items.empty() )
295 return 0;
296
297 // Don't leave a freed pointer in the selection
299
300 commit.Modify( symbol, m_frame->GetScreen() );
301
302 std::set<LIB_ITEM*> toDelete;
303
304 for( EDA_ITEM* item : items )
305 {
306 if( item->Type() == LIB_PIN_T )
307 {
308 LIB_PIN* curr_pin = static_cast<LIB_PIN*>( item );
309 VECTOR2I pos = curr_pin->GetPosition();
310
311 toDelete.insert( curr_pin );
312
313 // when pin editing is synchronized, pins in the same position, with the same name
314 // in different units are also removed. But only one pin per unit (matching)
315 if( m_frame->SynchronizePins() )
316 {
317 std::vector<bool> got_unit( symbol->GetUnitCount() + 1 );
318
319 got_unit[curr_pin->GetUnit()] = true;
320
321 int curr_bodyStyle = curr_pin->GetBodyStyle();
322 ELECTRICAL_PINTYPE etype = curr_pin->GetType();
323 wxString name = curr_pin->GetName();
324 std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
325
326 for( LIB_PIN* pin : pins )
327 {
328 if( got_unit[pin->GetUnit()] )
329 continue;
330
331 if( pin->GetPosition() != pos )
332 continue;
333
334 if( pin->GetBodyStyle() != curr_bodyStyle )
335 continue;
336
337 if( pin->GetType() != etype )
338 continue;
339
340 if( pin->GetName() != name )
341 continue;
342
343 toDelete.insert( pin );
344 got_unit[pin->GetUnit()] = true;
345 }
346 }
347 }
348 else
349 {
350 toDelete.insert( (LIB_ITEM*) item );
351 }
352 }
353
354 for( LIB_ITEM* item : toDelete )
355 symbol->RemoveDrawItem( item );
356
357 commit.Push( _( "Delete" ) );
359 return 0;
360}
361
362
363#define HITTEST_THRESHOLD_PIXELS 5
364
365
367{
369
371 m_pickerItem = nullptr;
372
373 // Deactivate other tools; particularly important if another PICKER is currently running
374 Activate();
375
376 picker->SetCursor( KICURSOR::REMOVE );
377
378 picker->SetClickHandler(
379 [this]( const VECTOR2D& aPosition ) -> bool
380 {
381 if( m_pickerItem )
382 {
384 selectionTool->UnbrightenItem( m_pickerItem );
385 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
387 m_pickerItem = nullptr;
388 }
389
390 return true;
391 } );
392
393 picker->SetMotionHandler(
394 [this]( const VECTOR2D& aPos )
395 {
397 EE_COLLECTOR collector;
398
399 selectionTool->CollectHits( collector, aPos, nonFields );
400
401 // Remove unselectable items
402 for( int i = collector.GetCount() - 1; i >= 0; --i )
403 {
404 if( !selectionTool->Selectable( collector[ i ] ) )
405 collector.Remove( i );
406 }
407
408 if( collector.GetCount() > 1 )
409 selectionTool->GuessSelectionCandidates( collector, aPos );
410
411 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
412
413 if( m_pickerItem != item )
414 {
415 if( m_pickerItem )
416 selectionTool->UnbrightenItem( m_pickerItem );
417
418 m_pickerItem = item;
419
420 if( m_pickerItem )
421 selectionTool->BrightenItem( m_pickerItem );
422 }
423 } );
424
425 picker->SetFinalizeHandler(
426 [this]( const int& aFinalState )
427 {
428 if( m_pickerItem )
429 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
430
431 // Wake the selection tool after exiting to ensure the cursor gets updated
433 } );
434
436
437 return 0;
438}
439
440
442{
444
445 if( selection.Empty() || aEvent.IsAction( &EE_ACTIONS::symbolProperties ) )
446 {
447 if( m_frame->GetCurSymbol() )
449 }
450 else if( selection.Size() == 1 )
451 {
452 LIB_ITEM* item = (LIB_ITEM*) selection.Front();
453
454 // Save copy for undo if not in edit (edit command already handle the save copy)
455 if( item->GetEditFlags() == 0 )
456 saveCopyInUndoList( item->GetParent(), UNDO_REDO::LIBEDIT );
457
458 switch( item->Type() )
459 {
460 case LIB_PIN_T:
462 pinTool->EditPinProperties( (LIB_PIN*) item );
463
464 break;
465
466 case LIB_SHAPE_T:
467 editShapeProperties( static_cast<LIB_SHAPE*>( item ) );
468 break;
469
470 case LIB_TEXT_T:
471 editTextProperties( item );
472 break;
473
474 case LIB_TEXTBOX_T:
475 editTextBoxProperties( item );
476 break;
477
478 case LIB_FIELD_T:
480 break;
481
482 default:
483 wxFAIL_MSG( wxT( "Unhandled item <" ) + item->GetClass() + wxT( ">" ) );
484 break;
485 }
486 }
487
488 if( selection.IsHover() )
490
491 return 0;
492}
493
494
496{
498
499 if( dlg.ShowModal() != wxID_OK )
500 return;
501
502 updateItem( aShape, true );
504 m_frame->OnModify();
505
508 drawingTools->SetDrawSpecificUnit( !dlg.GetApplyToAllUnits() );
509
510 std::vector<MSG_PANEL_ITEM> items;
511 aShape->GetMsgPanelInfo( m_frame, items );
512 m_frame->SetMsgPanel( items );
513}
514
515
517{
518 if ( aItem->Type() != LIB_TEXT_T )
519 return;
520
521 DIALOG_LIB_TEXT_PROPERTIES dlg( m_frame, static_cast<LIB_TEXT*>( aItem ) );
522
523 if( dlg.ShowModal() != wxID_OK )
524 return;
525
526 updateItem( aItem, true );
528 m_frame->OnModify( );
529}
530
531
533{
534 if ( aItem->Type() != LIB_TEXTBOX_T )
535 return;
536
537 DIALOG_LIB_TEXTBOX_PROPERTIES dlg( m_frame, static_cast<LIB_TEXTBOX*>( aItem ) );
538
539 if( dlg.ShowModal() != wxID_OK )
540 return;
541
542 updateItem( aItem, true );
544 m_frame->OnModify( );
545}
546
547
549{
550 if( aField == nullptr )
551 return;
552
553 wxString caption;
554 LIB_SYMBOL* parent = aField->GetParent();
555 wxCHECK( parent, /* void */ );
556
557 if( aField->GetId() >= 0 && aField->GetId() < MANDATORY_FIELDS )
558 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
559 else
560 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
561
562 DIALOG_LIB_FIELD_PROPERTIES dlg( m_frame, caption, aField );
563
564 // The dialog may invoke a kiway player for footprint fields
565 // so we must use a quasimodal dialog.
566 if( dlg.ShowQuasiModal() != wxID_OK )
567 return;
568
569 wxString newFieldValue = EscapeString( dlg.GetText(), CTX_LIBID );
570 wxString oldFieldValue = aField->GetFullText( m_frame->GetUnit() );
571
572 SCH_COMMIT commit( m_toolMgr );
573 commit.Modify( aField, m_frame->GetScreen() );
574
575 dlg.UpdateField( aField );
576
577 commit.Push( caption );
578
581}
582
583
585{
586 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
587 bool partLocked = symbol->UnitsLocked();
588
591
593
594 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
595 // frame. Therefore this dialog as a modal frame parent, MUST be run under
596 // quasimodal mode for the quasimodal frame support to work. So don't use
597 // the QUASIMODAL macros here.
598 if( dlg.ShowQuasiModal() != wxID_OK )
599 return;
600
601 m_frame->OnModify();
602
603 // if m_UnitSelectionLocked has changed, set some edit options or defaults
604 // to the best value
605 if( partLocked != symbol->UnitsLocked() )
606 {
608
609 // Enable synchronized pin edit mode for symbols with interchangeable units
610 m_frame->m_SyncPinEdit = !symbol->UnitsLocked();
611
612 // also set default edit options to the better value
613 // Usually if units are locked, graphic items are specific to each unit
614 // and if units are interchangeable, graphic items are common to units
615 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
616 }
617}
618
620 int& aSymbolLastPinNumber )
621{
622 if( !aNewPin->GetNumber().IsEmpty() )
623 {
624 // when duplicating a pin in symbol editor, assigning identical pin number
625 // to the old one does not makes any sense, so assign the next unassigned number to it
626 aSymbolLastPinNumber++;
627 aNewPin->SetNumber( wxString::Format( wxT( "%i" ), aSymbolLastPinNumber ) );
628 }
629}
630
632{
633 SCH_COMMIT commit( m_frame );
634 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
635
636 if( !symbol )
637 return 0;
638
639 commit.Modify( symbol );
640
642
643 DIALOG_LIB_EDIT_PIN_TABLE dlg( m_frame, symbol );
644
645 if( dlg.ShowModal() == wxID_CANCEL )
646 return -1;
647
648 commit.Push( _( "Edit Pins" ) );
650
651 return 0;
652}
653
654
656{
657 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
658
659 if( !symbol )
660 return 0;
661
662 if( !symbol->IsAlias() )
663 {
664 m_frame->ShowInfoBarError( _( "Symbol is not derived from another symbol." ) );
665 }
666 else
667 {
669
670 if( dlg.ShowModal() == wxID_CANCEL )
671 return -1;
672 }
673
674 return 0;
675}
676
677
679{
680 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
681
682 if( !symbol )
683 return 0;
684
685 int unitid = m_frame->GetUnit();
686
687 if( unitid == 0 )
688 {
689 return -1;
690 }
691
692 wxString promptText = wxString::Format( _( "Enter display name for unit %s" ),
693 symbol->GetUnitReference( unitid ) );
694 wxString currentvalue;
695
696 if( symbol->HasUnitDisplayName( unitid ) )
697 {
698 currentvalue = symbol->GetUnitDisplayName( unitid );
699 }
700
701 wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue );
702
703 if( dlg.ShowModal() == wxID_OK )
704 {
705 saveCopyInUndoList( symbol, UNDO_REDO::LIBEDIT );
706 symbol->SetUnitDisplayName( unitid, dlg.GetValue() );
708 m_frame->OnModify();
709 }
710 else
711 {
712 return -1;
713 }
714
715 return 0;
716}
717
718
720{
722
723 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
724 // it just clears the SELECTION's reference to them.
725 selTool->GetSelection().Clear();
726 {
728 }
729 selTool->RebuildSelection();
730
731 return 0;
732}
733
734
736{
738
739 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
740 // it just clears the SELECTION's reference to them.
741 selTool->GetSelection().Clear();
742 {
744 }
745 selTool->RebuildSelection();
746
747 return 0;
748}
749
750
752{
753 int retVal = Copy( aEvent );
754
755 if( retVal == 0 )
756 retVal = DoDelete( aEvent );
757
758 return retVal;
759}
760
761
763{
764 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
766
767 if( !symbol || !selection.GetSize() )
768 return 0;
769
770 for( LIB_ITEM& item : symbol->GetDrawItems() )
771 {
772 if( item.Type() == LIB_FIELD_T )
773 continue;
774
775 wxASSERT( !item.HasFlag( STRUCT_DELETED ) );
776
777 if( !item.IsSelected() )
778 item.SetFlags( STRUCT_DELETED );
779 }
780
781 LIB_SYMBOL* partCopy = new LIB_SYMBOL( *symbol );
782
783 STRING_FORMATTER formatter;
784 SCH_IO_KICAD_SEXPR::FormatLibSymbol( partCopy, formatter );
785
786 delete partCopy;
787
788 for( LIB_ITEM& item : symbol->GetDrawItems() )
790
791 if( m_toolMgr->SaveClipboard( formatter.GetString() ) )
792 return 0;
793 else
794 return -1;
795}
796
797
799{
800 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
801 LIB_SYMBOL* newPart = nullptr;
802
803 if( !symbol || symbol->IsAlias() )
804 return 0;
805
806 std::string clipboardData = m_toolMgr->GetClipboardUTF8();
807
808 try
809 {
810 std::vector<LIB_SYMBOL*> newParts = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
811
812 if( newParts.empty() || !newParts[0] )
813 return -1;
814
815 newPart = newParts[0];
816 }
817 catch( IO_ERROR& )
818 {
819 // If it's not a symbol then paste as text
820 newPart = new LIB_SYMBOL( "dummy_part" );
821 LIB_TEXT* newText = new LIB_TEXT( newPart );
822 newText->SetText( clipboardData );
823 newPart->AddDrawItem( newText );
824 }
825
826 SCH_COMMIT commit( m_toolMgr );
827
828 commit.Modify( symbol );
830
831 for( LIB_ITEM& item : symbol->GetDrawItems() )
832 item.ClearFlags( IS_NEW | IS_PASTED | SELECTED );
833
834 for( LIB_ITEM& item : newPart->GetDrawItems() )
835 {
836 if( item.Type() == LIB_FIELD_T )
837 continue;
838
839 LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
840 newItem->SetParent( symbol );
841 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
842
843 newItem->SetUnit( newItem->GetUnit() ? m_frame->GetUnit() : 0 );
844 newItem->SetBodyStyle( newItem->GetBodyStyle() ? m_frame->GetBodyStyle() : 0 );
845
846 symbol->AddDrawItem( newItem );
847 getView()->Add( newItem );
848 }
849
850 delete newPart;
851
853
855
856 if( !selection.Empty() )
857 {
858 selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
859
861 commit.Push( _( "Paste" ) );
862 else
863 commit.Revert();
864 }
865
866 return 0;
867}
868
869
871{
872 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
874 SCH_COMMIT commit( m_toolMgr );
875
876 if( selection.GetSize() == 0 )
877 return 0;
878
879 commit.Modify( symbol, m_frame->GetScreen() );
880
881 EDA_ITEMS newItems;
882
883 for( unsigned ii = 0; ii < selection.GetSize(); ++ii )
884 {
885 LIB_ITEM* oldItem = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
886 LIB_ITEM* newItem = static_cast<LIB_ITEM*>( oldItem->Duplicate() );
887
888 if( newItem->Type() == LIB_PIN_T )
889 {
890 LIB_PIN* newPin = static_cast<LIB_PIN*>( newItem );
891
892 if( !newPin->GetNumber().IsEmpty() )
893 newPin->SetNumber( wxString::Format( wxT( "%i" ), symbol->GetMaxPinNumber() + 1 ) );
894 }
895
896 oldItem->ClearFlags( IS_NEW | IS_PASTED | SELECTED );
897 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
898 newItem->SetParent( symbol );
899 newItems.push_back( newItem );
900
901 symbol->AddDrawItem( newItem );
902 getView()->Add( newItem );
903 }
904
907
908 selection.SetReferencePoint( mapCoords( getViewControls()->GetCursorPosition( true ) ) );
909
911 commit.Push( _( "Duplicate" ) );
912 else
913 commit.Revert();
914
915 return 0;
916}
917
918
920{
927
934
940}
const char * name
Definition: DXF_plotter.cpp:57
VECTOR2D mapCoords(const VECTOR2D &aSource)
Definition: PS_plotter.cpp:531
static TOOL_ACTION paste
Definition: actions.h:70
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
static TOOL_ACTION unselectAll
Definition: actions.h:73
static TOOL_ACTION copy
Definition: actions.h:69
static TOOL_ACTION pickerTool
Definition: actions.h:189
static TOOL_ACTION undo
Definition: actions.h:66
static TOOL_ACTION duplicate
Definition: actions.h:74
static TOOL_ACTION doDelete
Definition: actions.h:75
static TOOL_ACTION redo
Definition: actions.h:67
static TOOL_ACTION deleteTool
Definition: actions.h:76
static TOOL_ACTION cut
Definition: actions.h:68
static TOOL_ACTION refreshPreview
Definition: actions.h:137
static TOOL_ACTION selectAll
Definition: actions.h:72
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.
const wxString & GetText() const
Handle editing a single symbol field in the symbol editor.
Dialog to edit library component graphic items.
int ShowQuasiModal()
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:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:239
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:129
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:125
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
bool IsMoving() const
Definition: eda_item.h:104
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:276
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:161
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:164
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:268
static TOOL_ACTION mirrorV
Definition: ee_actions.h:123
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
static TOOL_ACTION properties
Definition: ee_actions.h:126
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:118
static TOOL_ACTION pinTable
Definition: ee_actions.h:153
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:122
static TOOL_ACTION mirrorH
Definition: ee_actions.h:124
static TOOL_ACTION rotateCW
Definition: ee_actions.h:121
static TOOL_ACTION symbolProperties
Definition: ee_actions.h:152
static TOOL_ACTION setUnitDisplayName
Definition: ee_actions.h:211
static TOOL_ACTION updateSymbolFields
Definition: ee_actions.h:210
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 void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:315
Field object used in symbol libraries.
Definition: lib_field.h:62
wxString GetClass() const override
Return the class name.
Definition: lib_field.h:72
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: lib_field.cpp:406
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: lib_field.cpp:485
int GetId() const
Definition: lib_field.h:120
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:68
int GetBodyStyle() const
Definition: lib_item.h:346
int GetUnit() const
Definition: lib_item.h:343
virtual void MirrorHorizontal(const VECTOR2I &aCenter)=0
Mirror the draw object along the horizontal (X) axis about aCenter point.
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW=true)=0
Rotate the object about aCenter point.
LIB_ITEM * Duplicate() const
Create a copy of this LIB_ITEM (with a new Uuid).
Definition: lib_item.cpp:131
virtual void MirrorVertical(const VECTOR2I &aCenter)=0
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
void SetBodyStyle(int aBodyStyle)
Definition: lib_item.h:345
LIB_SYMBOL * GetParent() const
Definition: lib_item.h:209
void SetUnit(int aUnit)
Definition: lib_item.h:342
ELECTRICAL_PINTYPE GetType() const
Definition: lib_pin.h:84
VECTOR2I GetPosition() const override
Definition: lib_pin.h:232
const wxString & GetNumber() const
Definition: lib_pin.h:117
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:119
const wxString & GetName() const
Definition: lib_pin.h:106
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_shape.cpp:448
Define a library symbol object.
Definition: lib_symbol.h:99
void RemoveDrawItem(LIB_ITEM *aItem)
Remove draw aItem from list.
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:286
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:551
bool IsAlias() const
Definition: lib_symbol.h:215
int GetMaxPinNumber() const
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:545
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
bool HasUnitDisplayName(int aUnit) override
Return true if the given unit aUnit has a display name defined.
Definition: lib_symbol.cpp:545
wxString GetUnitReference(int aUnit) override
Return an identifier for aUnit for symbols with units.
Definition: lib_symbol.cpp:539
std::vector< LIB_PIN * > GetAllLibPins() const
Return a list of pin pointers for all units / converts.
int GetUnitCount() const override
For items with units, return the number of units.
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:573
Define a symbol library graphical text item.
Definition: lib_text.h:40
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:83
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:72
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:63
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:103
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:393
virtual void Revert() override
Definition: sch_commit.cpp:474
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)
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
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.
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
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:120
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:93
bool IsHover() const
Definition: selection.h:83
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:99
EDA_ITEM * Front() const
Definition: selection.h:208
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:92
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:179
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:433
const std::string & GetString()
Definition: richio.h:456
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.
int PinTable(const TOOL_EVENT &aEvent)
void handlePinDuplication(LIB_PIN *aOldPin, LIB_PIN *aNewPin, int &aSymbolLastPinNumber)
Set up handlers for various events.
int Copy(const TOOL_EVENT &aEvent)
void editShapeProperties(LIB_SHAPE *aShape)
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 editFieldProperties(LIB_FIELD *aField)
void editTextProperties(LIB_ITEM *aItem)
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 editTextBoxProperties(LIB_ITEM *aItem)
The symbol library editor main window.
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
int GetBodyStyle() const
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
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:216
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
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:145
std::string GetClipboardUTF8() const
Return the information currently stored in the system clipboard.
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:230
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
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:192
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
#define _(s)
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:529
#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
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:36
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
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
#define TO_VJUSTIFY(x)
#define TO_HJUSTIFY(x)
@ LIB_SYMBOL_T
Definition: typeinfo.h:202
@ LIB_TEXT_T
Definition: typeinfo.h:204
@ LIB_TEXTBOX_T
Definition: typeinfo.h:205
@ LIB_SHAPE_T
Definition: typeinfo.h:203
@ LIB_PIN_T
Definition: typeinfo.h:206
@ LIB_FIELD_T
Definition: typeinfo.h:212