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 The 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>
33#include <clipboard.h>
34#include <sch_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
53
55 SCH_TOOL_BASE( "eeschema.SymbolEditTool" ),
56 m_pickerItem( nullptr )
57{
58}
59
60
62{
64
67
68 wxASSERT_MSG( drawingTools, "eeschema.SymbolDrawing tool is not available" );
69
70 auto haveSymbolCondition =
71 [&]( const SELECTION& sel )
72 {
74 };
75
76 auto canEdit =
77 [&]( const SELECTION& sel )
78 {
80 return false;
81
82 if( m_frame->IsSymbolAlias() )
83 {
84 for( EDA_ITEM* item : sel )
85 {
86 if( item->Type() != SCH_FIELD_T )
87 return false;
88 }
89 }
90
91 return true;
92 };
93
94 const auto canCopyText = SCH_CONDITIONS::OnlyTypes( {
101 } );
102
103 // clang-format off
104 // Add edit actions to the move tool menu
105 if( moveTool )
106 {
107 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
108
109 moveMenu.AddSeparator( 200 );
110 moveMenu.AddItem( SCH_ACTIONS::rotateCCW, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
111 moveMenu.AddItem( SCH_ACTIONS::rotateCW, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
112 moveMenu.AddItem( SCH_ACTIONS::mirrorV, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
113 moveMenu.AddItem( SCH_ACTIONS::mirrorH, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
114
115 moveMenu.AddItem( SCH_ACTIONS::swap, canEdit && SELECTION_CONDITIONS::MoreThan( 1 ), 200);
116 moveMenu.AddItem( SCH_ACTIONS::properties, canEdit && SCH_CONDITIONS::Count( 1 ), 200 );
117
118 moveMenu.AddSeparator( 300 );
121 moveMenu.AddItem( ACTIONS::copyAsText, canCopyText && SCH_CONDITIONS::IdleSelection, 300 );
122 moveMenu.AddItem( ACTIONS::duplicate, canEdit && SCH_CONDITIONS::NotEmpty, 300 );
123 moveMenu.AddItem( ACTIONS::doDelete, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
124
125 moveMenu.AddSeparator( 400 );
126 moveMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
127 moveMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
128 }
129
130 // Add editing actions to the drawing tool menu
131 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
132
133 drawMenu.AddSeparator( 200 );
138
139 drawMenu.AddItem( SCH_ACTIONS::properties, canEdit && SCH_CONDITIONS::Count( 1 ), 200 );
140
141 // Add editing actions to the selection tool menu
143
144 selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
145 selToolMenu.AddItem( SCH_ACTIONS::rotateCW, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
146 selToolMenu.AddItem( SCH_ACTIONS::mirrorV, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
147 selToolMenu.AddItem( SCH_ACTIONS::mirrorH, canEdit && SCH_CONDITIONS::NotEmpty, 200 );
148
149 selToolMenu.AddItem( SCH_ACTIONS::swap, canEdit && SELECTION_CONDITIONS::MoreThan( 1 ), 200 );
150 selToolMenu.AddItem( SCH_ACTIONS::properties, canEdit && SCH_CONDITIONS::Count( 1 ), 200 );
151
152 selToolMenu.AddSeparator( 300 );
155 selToolMenu.AddItem( ACTIONS::copyAsText, canCopyText && SCH_CONDITIONS::IdleSelection, 300 );
156 selToolMenu.AddItem( ACTIONS::paste, canEdit && SCH_CONDITIONS::Idle, 300 );
157 selToolMenu.AddItem( ACTIONS::duplicate, canEdit && SCH_CONDITIONS::NotEmpty, 300 );
158 selToolMenu.AddItem( ACTIONS::doDelete, canEdit && SCH_CONDITIONS::NotEmpty, 300 );
159
160 selToolMenu.AddSeparator( 400 );
161 selToolMenu.AddItem( ACTIONS::selectAll, haveSymbolCondition, 400 );
162 selToolMenu.AddItem( ACTIONS::unselectAll, haveSymbolCondition, 400 );
163 // clang-format on
164
165 return true;
166}
167
168
170{
172
173 if( selection.GetSize() == 0 )
174 return 0;
175
176 VECTOR2I rotPoint;
177 bool ccw = ( aEvent.Matches( SCH_ACTIONS::rotateCCW.MakeEvent() ) );
178 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
179 SCH_COMMIT localCommit( m_toolMgr );
180 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
181
182 if( !commit )
183 commit = &localCommit;
184
185 if( !item->IsMoving() )
186 commit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen(), RECURSE_MODE::RECURSE );
187
188 if( selection.GetSize() == 1 )
189 rotPoint = item->GetPosition();
190 else
191 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
192
193 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
194 {
195 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
196 item->Rotate( rotPoint, ccw );
197 m_frame->UpdateItem( item, false, true );
198 }
199
200 if( item->IsMoving() )
201 {
203 }
204 else
205 {
206 if( selection.IsHover() )
208
209 if( !localCommit.Empty() )
210 localCommit.Push( _( "Rotate" ) );
211 }
212
213 return 0;
214}
215
216
218{
220
221 if( selection.GetSize() == 0 )
222 return 0;
223
224 VECTOR2I mirrorPoint;
225 bool xAxis = ( aEvent.Matches( SCH_ACTIONS::mirrorV.MakeEvent() ) );
226 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
227
228 if( !item->IsMoving() )
229 saveCopyInUndoList( m_frame->GetCurSymbol(), UNDO_REDO::LIBEDIT );
230
231 if( selection.GetSize() == 1 )
232 {
233 mirrorPoint = item->GetPosition();
234
235 switch( item->Type() )
236 {
237 case SCH_FIELD_T:
238 {
239 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
240
241 if( xAxis )
243 else
245
246 break;
247 }
248
249 default:
250 if( xAxis )
251 item->MirrorVertically( mirrorPoint.y );
252 else
253 item->MirrorHorizontally( mirrorPoint.x );
254
255 break;
256 }
257
258
259 m_frame->UpdateItem( item, false, true );
260 }
261 else
262 {
263 mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
264
265 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
266 {
267 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
268
269 if( xAxis )
270 item->MirrorVertically( mirrorPoint.y );
271 else
272 item->MirrorHorizontally( mirrorPoint.x );
273
274 m_frame->UpdateItem( item, false, true );
275 }
276 }
277
278 if( item->IsMoving() )
279 {
281 }
282 else
283 {
284 if( selection.IsHover() )
286
287 m_frame->OnModify();
288 }
289
290 return 0;
291}
292
293
294const std::vector<KICAD_T> swappableItems = {
295 LIB_SYMBOL_T, // Allows swapping the anchor
296 SCH_PIN_T,
301};
302
303
305{
307 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
308
309 if( selection.Size() < 2 )
310 return 0;
311
312 EDA_ITEM* front = selection.Front();
313 bool isMoving = front->IsMoving();
314
315 // Save copy for undo if not in edit (edit command already handle the save copy)
316 if( front->GetEditFlags() == 0 )
317 saveCopyInUndoList( front->GetParent(), UNDO_REDO::LIBEDIT );
318
319 for( size_t i = 0; i < sorted.size() - 1; i++ )
320 {
321 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
322 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
323
324 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
325 std::swap( aPos, bPos );
326
327 a->SetPosition( aPos );
328 b->SetPosition( bPos );
329
330 // Special case some common swaps
331 if( a->Type() == b->Type() )
332 {
333 switch( a->Type() )
334 {
335 case SCH_PIN_T:
336 {
337 SCH_PIN* aPin = static_cast<SCH_PIN*>( a );
338 SCH_PIN* bBpin = static_cast<SCH_PIN*>( b );
339
340 PIN_ORIENTATION aOrient = aPin->GetOrientation();
341 PIN_ORIENTATION bOrient = bBpin->GetOrientation();
342
343 aPin->SetOrientation( bOrient );
344 bBpin->SetOrientation( aOrient );
345
346 break;
347 }
348 default: break;
349 }
350 }
351
352 m_frame->UpdateItem( a, false, true );
353 m_frame->UpdateItem( b, false, true );
354 }
355
356 // Update R-Tree for modified items
357 for( EDA_ITEM* selected : selection )
358 updateItem( selected, true );
359
360 if( isMoving )
361 {
363 }
364 else
365 {
366 if( selection.IsHover() )
368
369 m_frame->OnModify();
370 }
371
372 return 0;
373}
374
375
376static std::vector<KICAD_T> nonFields =
377{
383};
384
385
387{
388 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
389 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection().GetItems();
390 SCH_COMMIT commit( m_frame );
391
392 if( items.empty() )
393 return 0;
394
395 // Don't leave a freed pointer in the selection
397
398 commit.Modify( symbol, m_frame->GetScreen() );
399
400 std::set<SCH_ITEM*> toDelete;
401 int fieldsHidden = 0;
402 int fieldsAlreadyHidden = 0;
403
404 for( EDA_ITEM* item : items )
405 {
406 if( item->Type() == SCH_PIN_T )
407 {
408 SCH_PIN* curr_pin = static_cast<SCH_PIN*>( item );
409 VECTOR2I pos = curr_pin->GetPosition();
410
411 toDelete.insert( curr_pin );
412
413 // when pin editing is synchronized, pins in the same position, with the same name
414 // in different units are also removed. But only one pin per unit (matching)
415 if( m_frame->SynchronizePins() )
416 {
417 std::vector<bool> got_unit( symbol->GetUnitCount() + 1 );
418
419 got_unit[curr_pin->GetUnit()] = true;
420
421 for( SCH_PIN* pin : symbol->GetPins() )
422 {
423 if( got_unit[pin->GetUnit()] )
424 continue;
425
426 if( pin->GetPosition() != pos )
427 continue;
428
429 if( pin->GetBodyStyle() != curr_pin->GetBodyStyle() )
430 continue;
431
432 if( pin->GetType() != curr_pin->GetType() )
433 continue;
434
435 if( pin->GetName() != curr_pin->GetName() )
436 continue;
437
438 toDelete.insert( pin );
439 got_unit[pin->GetUnit()] = true;
440 }
441 }
442 }
443 else if( item->Type() == SCH_FIELD_T )
444 {
445 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
446
447 // Hide "deleted" fields
448 if( field->IsVisible() )
449 {
450 field->SetVisible( false );
451 fieldsHidden++;
452 }
453 else
454 {
455 fieldsAlreadyHidden++;
456 }
457 }
458 else if( SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item ) )
459 {
460 toDelete.insert( schItem );
461 }
462 }
463
464 for( SCH_ITEM* item : toDelete )
465 symbol->RemoveDrawItem( item );
466
467 if( toDelete.size() == 0 )
468 {
469 if( fieldsHidden == 1 )
470 commit.Push( _( "Hide Field" ) );
471 else if( fieldsHidden > 1 )
472 commit.Push( _( "Hide Fields" ) );
473 else if( fieldsAlreadyHidden > 0 )
474 m_frame->ShowInfoBarError( _( "Use the Symbol Properties dialog to remove fields." ) );
475 }
476 else
477 {
478 commit.Push( _( "Delete" ) );
479 }
480
482 return 0;
483}
484
485
486#define HITTEST_THRESHOLD_PIXELS 5
487
488
490{
492
494 m_pickerItem = nullptr;
495
496 // Deactivate other tools; particularly important if another PICKER is currently running
497 Activate();
498
499 picker->SetCursor( KICURSOR::REMOVE );
500 picker->SetSnapping( false );
501 picker->ClearHandlers();
502
503 picker->SetClickHandler(
504 [this]( const VECTOR2D& aPosition ) -> bool
505 {
506 if( m_pickerItem )
507 {
509 selectionTool->UnbrightenItem( m_pickerItem );
510 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
512 m_pickerItem = nullptr;
513 }
514
515 return true;
516 } );
517
518 picker->SetMotionHandler(
519 [this]( const VECTOR2D& aPos )
520 {
522 SCH_COLLECTOR collector;
523
524 selectionTool->CollectHits( collector, aPos, nonFields );
525
526 // Remove unselectable items
527 for( int i = collector.GetCount() - 1; i >= 0; --i )
528 {
529 if( !selectionTool->Selectable( collector[ i ] ) )
530 collector.Remove( i );
531 }
532
533 if( collector.GetCount() > 1 )
534 selectionTool->GuessSelectionCandidates( collector, aPos );
535
536 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
537
538 if( m_pickerItem != item )
539 {
540 if( m_pickerItem )
541 selectionTool->UnbrightenItem( m_pickerItem );
542
543 m_pickerItem = item;
544
545 if( m_pickerItem )
546 selectionTool->BrightenItem( m_pickerItem );
547 }
548 } );
549
550 picker->SetFinalizeHandler(
551 [this]( const int& aFinalState )
552 {
553 if( m_pickerItem )
554 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
555
556 // Wake the selection tool after exiting to ensure the cursor gets updated
558 } );
559
561
562 return 0;
563}
564
565
567{
569
570 if( selection.Empty() || aEvent.IsAction( &SCH_ACTIONS::symbolProperties ) )
571 {
572 if( m_frame->GetCurSymbol() )
574 }
575 else if( selection.Size() == 1 )
576 {
577 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
578
579 // Save copy for undo if not in edit (edit command already handle the save copy)
580 if( item->GetEditFlags() == 0 )
581 saveCopyInUndoList( item->GetParent(), UNDO_REDO::LIBEDIT );
582
583 switch( item->Type() )
584 {
585 case SCH_PIN_T:
586 {
587 SCH_PIN& pin = static_cast<SCH_PIN&>( *item );
588
589 // Mouse, not cursor, as grid points may well not be under any text
590 const VECTOR2I& mousePos = m_toolMgr->GetMousePosition();
591 PIN_LAYOUT_CACHE& layout = pin.GetLayoutCache();
592
593 bool mouseOverNumber = false;
594 if( OPT_BOX2I numberBox = layout.GetPinNumberBBox() )
595 {
596 mouseOverNumber = numberBox->Contains( mousePos );
597 }
598
600 pinTool->EditPinProperties( &pin, mouseOverNumber );
601
602 break;
603 }
604 case SCH_SHAPE_T:
605 editShapeProperties( static_cast<SCH_SHAPE*>( item ) );
606 break;
607
608 case SCH_TEXT_T:
609 editTextProperties( item );
610 break;
611
612 case SCH_TEXTBOX_T:
613 editTextBoxProperties( item );
614 break;
615
616 case SCH_FIELD_T:
617 editFieldProperties( static_cast<SCH_FIELD*>( item ) );
618 break;
619
620 default:
621 wxFAIL_MSG( wxT( "Unhandled item <" ) + item->GetClass() + wxT( ">" ) );
622 break;
623 }
624 }
625
626 if( selection.IsHover() )
628
629 return 0;
630}
631
632
634{
635 DIALOG_SHAPE_PROPERTIES dlg( m_frame, aShape );
636
637 if( dlg.ShowModal() != wxID_OK )
638 return;
639
640 updateItem( aShape, true );
642 m_frame->OnModify();
643
646 drawingTools->SetDrawSpecificUnit( !dlg.GetApplyToAllUnits() );
647
648 std::vector<MSG_PANEL_ITEM> items;
649 aShape->GetMsgPanelInfo( m_frame, items );
650 m_frame->SetMsgPanel( items );
651}
652
653
655{
656 if ( aItem->Type() != SCH_TEXT_T )
657 return;
658
659 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_TEXT*>( aItem ) );
660
661 if( dlg.ShowModal() != wxID_OK )
662 return;
663
664 updateItem( aItem, true );
666 m_frame->OnModify( );
667}
668
669
671{
672 if ( aItem->Type() != SCH_TEXTBOX_T )
673 return;
674
675 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_TEXTBOX*>( aItem ) );
676
677 if( dlg.ShowModal() != wxID_OK )
678 return;
679
680 updateItem( aItem, true );
682 m_frame->OnModify( );
683}
684
685
687{
688 if( aField == nullptr )
689 return;
690
691 wxString caption;
692
693 if( aField->IsMandatory() )
694 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
695 else
696 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
697
698 DIALOG_FIELD_PROPERTIES dlg( m_frame, caption, aField );
699
700 // The dialog may invoke a kiway player for footprint fields
701 // so we must use a quasimodal dialog.
702 if( dlg.ShowQuasiModal() != wxID_OK )
703 return;
704
705 SCH_COMMIT commit( m_toolMgr );
706 commit.Modify( aField, m_frame->GetScreen() );
707
708 dlg.UpdateField( aField );
709
710 commit.Push( caption );
711
714}
715
716
718{
719 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
720 bool partLocked = symbol->UnitsLocked();
721
724
726
727 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
728 // frame. Therefore this dialog as a modal frame parent, MUST be run under
729 // quasimodal mode for the quasimodal frame support to work. So don't use
730 // the QUASIMODAL macros here.
731 if( dlg.ShowQuasiModal() != wxID_OK )
732 return;
733
734 m_frame->OnModify();
735
736 // if m_UnitSelectionLocked has changed, set some edit options or defaults
737 // to the best value
738 if( partLocked != symbol->UnitsLocked() )
739 {
741
742 // Enable synchronized pin edit mode for symbols with interchangeable units
743 m_frame->m_SyncPinEdit = !symbol->UnitsLocked();
744
745 // also set default edit options to the better value
746 // Usually if units are locked, graphic items are specific to each unit
747 // and if units are interchangeable, graphic items are common to units
748 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
749 }
750}
751
753 int& aSymbolLastPinNumber )
754{
755 if( !aNewPin->GetNumber().IsEmpty() )
756 {
757 // when duplicating a pin in symbol editor, assigning identical pin number
758 // to the old one does not makes any sense, so assign the next unassigned number to it
759 aSymbolLastPinNumber++;
760 aNewPin->SetNumber( wxString::Format( wxT( "%i" ), aSymbolLastPinNumber ) );
761 }
762}
763
765{
766 SCH_COMMIT commit( m_frame );
767 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
768
769 if( !symbol )
770 return 0;
771
772 commit.Modify( symbol );
773
775 wxCHECK( selTool, -1 );
776
777 std::vector<SCH_PIN*> selectedPins;
778
779 SCH_SELECTION& selection = selTool->GetSelection();
780
781 for( EDA_ITEM* item : selection )
782 {
783 if( item->Type() == SCH_PIN_T )
784 {
785 SCH_PIN* pinItem = static_cast<SCH_PIN*>( item );
786 selectedPins.push_back( pinItem );
787 }
788 }
789
790 // And now clear the selection so if we change the pins we don't have dangling pointers
791 // in the selection.
793
794 DIALOG_LIB_EDIT_PIN_TABLE dlg( m_frame, symbol, selectedPins );
795
796 if( dlg.ShowModal() == wxID_CANCEL )
797 return -1;
798
799 commit.Push( _( "Edit Pins" ) );
801
802 return 0;
803}
804
805
807{
808 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
809
810 if( !symbol )
811 return 0;
812
813 if( !symbol->IsDerived() )
814 {
815 m_frame->ShowInfoBarError( _( "Symbol is not derived from another symbol." ) );
816 }
817 else
818 {
820
821 if( dlg.ShowModal() == wxID_CANCEL )
822 return -1;
823 }
824
825 return 0;
826}
827
828
830{
831 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
832
833 if( !symbol )
834 return 0;
835
836 int unitid = m_frame->GetUnit();
837
838 if( unitid == 0 )
839 {
840 return -1;
841 }
842
843 wxString promptText = wxString::Format( _( "Enter display name for unit %s" ),
844 LIB_SYMBOL::LetterSubReference( unitid, 'A' ) );
845 wxString currentvalue;
846
847 if( symbol->HasUnitDisplayName( unitid ) )
848 currentvalue = symbol->GetUnitDisplayName( unitid, false );
849
850 wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue );
851
852 if( dlg.ShowModal() == wxID_OK )
853 {
854 saveCopyInUndoList( symbol, UNDO_REDO::LIBEDIT );
855 symbol->SetUnitDisplayName( unitid, dlg.GetValue() );
857 m_frame->OnModify();
858 }
859 else
860 {
861 return -1;
862 }
863
864 return 0;
865}
866
867
869{
871
872 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
873 // it just clears the SELECTION's reference to them.
874 selTool->GetSelection().Clear();
875 {
877 }
878 selTool->RebuildSelection();
879
880 return 0;
881}
882
883
885{
887
888 // Nuke the selection for later rebuilding. This does *not* clear the flags on any items;
889 // it just clears the SELECTION's reference to them.
890 selTool->GetSelection().Clear();
891 {
893 }
894 selTool->RebuildSelection();
895
896 return 0;
897}
898
899
901{
902 int retVal = Copy( aEvent );
903
904 if( retVal == 0 )
905 retVal = DoDelete( aEvent );
906
907 return retVal;
908}
909
910
912{
913 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
915
916 if( !symbol || !selection.GetSize() )
917 return 0;
918
919 for( SCH_ITEM& item : symbol->GetDrawItems() )
920 {
921 if( item.Type() == SCH_FIELD_T )
922 continue;
923
924 wxASSERT( !item.HasFlag( STRUCT_DELETED ) );
925
926 if( !item.IsSelected() )
927 item.SetFlags( STRUCT_DELETED );
928 }
929
930 LIB_SYMBOL* partCopy = new LIB_SYMBOL( *symbol );
931
932 STRING_FORMATTER formatter;
933 SCH_IO_KICAD_SEXPR::FormatLibSymbol( partCopy, formatter );
934
935 delete partCopy;
936
937 for( SCH_ITEM& item : symbol->GetDrawItems() )
939
940 std::string prettyData = formatter.GetString();
941 KICAD_FORMAT::Prettify( prettyData, true );
942
943 if( SaveClipboard( prettyData ) )
944 return 0;
945 else
946 return -1;
947}
948
949
951{
953 SCH_SELECTION& selection = selTool->RequestSelection();
954
955 if( selection.Empty() )
956 return 0;
957
958 wxString itemsAsText = GetSelectedItemsAsText( selection );
959
960 if( selection.IsHover() )
962
963 return SaveClipboard( itemsAsText.ToStdString() );
964}
965
966
968{
969 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
970 LIB_SYMBOL* newPart = nullptr;
971
972 if( !symbol || symbol->IsDerived() )
973 return 0;
974
975 std::string clipboardData = GetClipboardUTF8();
976
977 try
978 {
979 std::vector<LIB_SYMBOL*> newParts = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
980
981 if( newParts.empty() || !newParts[0] )
982 return -1;
983
984 newPart = newParts[0];
985 }
986 catch( IO_ERROR& )
987 {
988 // If it's not a symbol then paste as text
989 newPart = new LIB_SYMBOL( "dummy_part" );
990
991 wxString pasteText( clipboardData );
992
993 // Limit of 5000 is totally arbitrary. Without a limit, pasting a bitmap image from
994 // eeschema makes KiCad appear to hang.
995 if( pasteText.Length() > 5000 )
996 pasteText = pasteText.Left( 5000 ) + wxT( "..." );
997
998 SCH_TEXT* newText = new SCH_TEXT( { 0, 0 }, pasteText, LAYER_DEVICE );
999 newPart->AddDrawItem( newText );
1000 }
1001
1002 SCH_COMMIT commit( m_toolMgr );
1003
1004 commit.Modify( symbol );
1006
1007 for( SCH_ITEM& item : symbol->GetDrawItems() )
1008 item.ClearFlags( IS_NEW | IS_PASTED | SELECTED );
1009
1010 for( SCH_ITEM& item : newPart->GetDrawItems() )
1011 {
1012 if( item.Type() == SCH_FIELD_T )
1013 continue;
1014
1015 SCH_ITEM* newItem = item.Duplicate( true, &commit );
1016 newItem->SetParent( symbol );
1017 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
1018
1019 newItem->SetUnit( newItem->GetUnit() ? m_frame->GetUnit() : 0 );
1020 newItem->SetBodyStyle( newItem->GetBodyStyle() ? m_frame->GetBodyStyle() : 0 );
1021
1022 symbol->AddDrawItem( newItem );
1023 getView()->Add( newItem );
1024 }
1025
1026 delete newPart;
1027
1029
1031
1032 if( !selection.Empty() )
1033 {
1034 selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
1035
1037 commit.Push( _( "Paste" ) );
1038 else
1039 commit.Revert();
1040 }
1041
1042 return 0;
1043}
1044
1045
1047{
1048 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
1050 SCH_COMMIT commit( m_toolMgr );
1051
1052 if( selection.GetSize() == 0 )
1053 return 0;
1054
1055 commit.Modify( symbol, m_frame->GetScreen() );
1056
1057 std::vector<EDA_ITEM*> oldItems;
1058 std::vector<EDA_ITEM*> newItems;
1059
1060 std::copy( selection.begin(), selection.end(), std::back_inserter( oldItems ) );
1061 std::sort( oldItems.begin(), oldItems.end(), []( EDA_ITEM* a, EDA_ITEM* b )
1062 {
1063 int cmp;
1064
1065 if( a->Type() != b->Type() )
1066 return a->Type() < b->Type();
1067
1068 // Create the new pins in the same order as the old pins
1069 if( a->Type() == SCH_PIN_T )
1070 {
1071 const wxString& aNum = static_cast<SCH_PIN*>( a )->GetNumber();
1072 const wxString& bNum = static_cast<SCH_PIN*>( b )->GetNumber();
1073
1074 cmp = StrNumCmp( aNum, bNum );
1075
1076 // If the pin numbers are not numeric, then just number them by their position
1077 // on the screen.
1078 if( aNum.IsNumber() && bNum.IsNumber() && cmp != 0 )
1079 return cmp < 0;
1080 }
1081
1083
1084 if( cmp != 0 )
1085 return cmp < 0;
1086
1087 return a->m_Uuid < b->m_Uuid;
1088 } );
1089
1090 for( EDA_ITEM* item : oldItems )
1091 {
1092 SCH_ITEM* oldItem = static_cast<SCH_ITEM*>( item );
1093 SCH_ITEM* newItem = oldItem->Duplicate( true, &commit );
1094
1095 if( newItem->Type() == SCH_PIN_T )
1096 {
1097 SCH_PIN* newPin = static_cast<SCH_PIN*>( newItem );
1098
1099 if( !newPin->GetNumber().IsEmpty() )
1100 newPin->SetNumber( wxString::Format( wxT( "%i" ), symbol->GetMaxPinNumber() + 1 ) );
1101 }
1102
1103 oldItem->ClearFlags( IS_NEW | IS_PASTED | SELECTED );
1104 newItem->SetFlags( IS_NEW | IS_PASTED | SELECTED );
1105 newItem->SetParent( symbol );
1106 newItems.push_back( newItem );
1107
1108 symbol->AddDrawItem( newItem );
1109 getView()->Add( newItem );
1110 }
1111
1112 m_toolMgr->RunAction( ACTIONS::selectionClear );
1113 m_toolMgr->RunAction<EDA_ITEMS*>( ACTIONS::selectItems, &newItems );
1114
1115 selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
1116
1117 if( m_toolMgr->RunSynchronousAction( SCH_ACTIONS::move, &commit ) )
1118 commit.Push( _( "Duplicate" ) );
1119 else
1120 commit.Revert();
1121
1122 return 0;
1123}
1124
1125
1127{
1128 const ACTIONS::INCREMENT incParam = aEvent.Parameter<ACTIONS::INCREMENT>();
1130
1131 if( selection.Empty() )
1132 return 0;
1133
1134 KICAD_T type = selection.Front()->Type();
1135 bool allSameType = true;
1136 for( EDA_ITEM* item : selection )
1137 {
1138 if( item->Type() != type )
1139 {
1140 allSameType = false;
1141 break;
1142 }
1143 }
1144
1145 // Incrementing multiple types at once seems confusing
1146 // though it would work.
1147 if( !allSameType )
1148 return 0;
1149
1150 const VECTOR2I mousePosition = getViewControls()->GetMousePosition();
1151
1152 STRING_INCREMENTER incrementer;
1153 incrementer.SetSkipIOSQXZ( true );
1154
1155 // If we're coming via another action like 'Move', use that commit
1156 SCH_COMMIT localCommit( m_toolMgr );
1157 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
1158
1159 if( !commit )
1160 commit = &localCommit;
1161
1162 const auto modifyItem = [&]( EDA_ITEM& aItem )
1163 {
1164 if( aItem.IsNew() )
1166 else
1167 commit->Modify( &aItem, m_frame->GetScreen() );
1168 };
1169
1170 for( EDA_ITEM* item : selection )
1171 {
1172 switch( item->Type() )
1173 {
1174 case SCH_PIN_T:
1175 {
1176 SCH_PIN& pin = static_cast<SCH_PIN&>( *item );
1177 PIN_LAYOUT_CACHE& layout = pin.GetLayoutCache();
1178
1179 bool found = false;
1180 OPT_BOX2I bbox = layout.GetPinNumberBBox();
1181
1182 if( bbox && bbox->Contains( mousePosition ) )
1183 {
1184 std::optional<wxString> nextNumber =
1185 incrementer.Increment( pin.GetNumber(), incParam.Delta, incParam.Index );
1186 if( nextNumber )
1187 {
1188 modifyItem( pin );
1189 pin.SetNumber( *nextNumber );
1190 }
1191 found = true;
1192 }
1193
1194 if( !found )
1195 {
1196 bbox = layout.GetPinNameBBox();
1197
1198 if( bbox && bbox->Contains( mousePosition ) )
1199 {
1200 std::optional<wxString> nextName =
1201 incrementer.Increment( pin.GetName(), incParam.Delta, incParam.Index );
1202 if( nextName )
1203 {
1204 modifyItem( pin );
1205 pin.SetName( *nextName );
1206 }
1207 found = true;
1208 }
1209 }
1210 break;
1211 }
1212 case SCH_TEXT_T:
1213 {
1214 SCH_TEXT& label = static_cast<SCH_TEXT&>( *item );
1215
1216 std::optional<wxString> newLabel =
1217 incrementer.Increment( label.GetText(), incParam.Delta, incParam.Index );
1218 if( newLabel )
1219 {
1220 modifyItem( label );
1221 label.SetText( *newLabel );
1222 }
1223 break;
1224 }
1225 default:
1226 // No increment for other items
1227 break;
1228 }
1229 }
1230
1231 commit->Push( _( "Increment" ) );
1232
1233 return 0;
1234}
1235
1236
1238{
1239 // clang-format off
1247
1255
1261
1267 // clang-format on
1268}
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:926
static TOOL_ACTION decrementPrimary
Definition: actions.h:96
static TOOL_ACTION paste
Definition: actions.h:80
static TOOL_ACTION cancelInteractive
Definition: actions.h:72
static TOOL_ACTION unselectAll
Definition: actions.h:83
static TOOL_ACTION decrementSecondary
Definition: actions.h:98
static TOOL_ACTION copy
Definition: actions.h:78
static TOOL_ACTION pickerTool
Definition: actions.h:250
static TOOL_ACTION undo
Definition: actions.h:75
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: actions.h:211
static TOOL_ACTION incrementSecondary
Definition: actions.h:97
static TOOL_ACTION duplicate
Definition: actions.h:84
static TOOL_ACTION incrementPrimary
Definition: actions.h:95
static TOOL_ACTION doDelete
Definition: actions.h:85
static TOOL_ACTION redo
Definition: actions.h:76
static TOOL_ACTION deleteTool
Definition: actions.h:86
static TOOL_ACTION increment
Definition: actions.h:94
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:221
static TOOL_ACTION cut
Definition: actions.h:77
static TOOL_ACTION copyAsText
Definition: actions.h:79
static TOOL_ACTION refreshPreview
Definition: actions.h:156
static TOOL_ACTION selectAll
Definition: actions.h:82
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: actions.h:229
bool Empty() const
Definition: commit.h:152
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
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)
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:98
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:272
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:273
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:148
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:144
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:113
EDA_ITEM * GetParent() const
Definition: eda_item.h:112
bool IsMoving() const
Definition: eda_item.h:125
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
virtual bool IsVisible() const
Definition: eda_text.h:184
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:417
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:197
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:386
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:200
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:270
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:409
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:298
Define a library symbol object.
Definition: lib_symbol.h:85
bool HasUnitDisplayName(int aUnit) const
Return true if the given unit aUnit has a display name defined.
Definition: lib_symbol.cpp:281
std::vector< SCH_PIN * > GetPins(int aUnit, int aBodyStyle) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:799
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:289
bool IsDerived() const
Definition: lib_symbol.h:207
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
Definition: lib_symbol.cpp:517
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:519
void RemoveDrawItem(SCH_ITEM *aItem)
Remove draw aItem from list.
Definition: lib_symbol.cpp:760
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:316
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:785
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:287
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:92
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:81
void SetSnapping(bool aSnap)
Definition: picker_tool.h:66
void ClearHandlers()
Definition: picker_tool.h:68
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:112
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.
static TOOL_ACTION rotateCCW
Definition: sch_actions.h:121
static TOOL_ACTION mirrorV
Definition: sch_actions.h:122
static TOOL_ACTION swap
Definition: sch_actions.h:124
static TOOL_ACTION pinTable
Definition: sch_actions.h:152
static TOOL_ACTION properties
Definition: sch_actions.h:125
static TOOL_ACTION rotateCW
Definition: sch_actions.h:120
static TOOL_ACTION setUnitDisplayName
Definition: sch_actions.h:214
static TOOL_ACTION mirrorH
Definition: sch_actions.h:123
static TOOL_ACTION symbolProperties
Definition: sch_actions.h:151
static TOOL_ACTION updateSymbolFields
Definition: sch_actions.h:213
static TOOL_ACTION move
Definition: sch_actions.h:117
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
Execute the changes.
Definition: sch_commit.cpp:489
virtual void Revert() override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:567
bool IsMandatory() const
Definition: sch_field.cpp:1359
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1103
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:168
SCH_ITEM * Duplicate(bool addToParentGroup, SCH_COMMIT *aCommit=nullptr, bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:137
virtual void SetBodyStyle(int aBodyStyle)
Definition: sch_item.h:247
int GetBodyStyle() const
Definition: sch_item.h:248
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
Definition: sch_item.h:377
int GetUnit() const
Definition: sch_item.h:239
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_item.h:394
virtual void SetUnit(int aUnit)
Definition: sch_item.h:238
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:178
virtual void MirrorVertically(int aCenter)
Mirror item vertically about aCenter.
Definition: sch_item.h:386
void SetNumber(const wxString &aNumber)
Definition: sch_pin.cpp:541
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: sch_pin.h:92
const wxString & GetName() const
Definition: sch_pin.cpp:357
PIN_ORIENTATION GetOrientation() const
Definition: sch_pin.cpp:220
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:212
const wxString & GetNumber() const
Definition: sch_pin.h:123
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:269
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
bool CollectHits(SCH_COLLECTOR &aCollector, const VECTOR2I &aWhere, const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T })
Collect one or more items at a given point.
void GuessSelectionCandidates(SCH_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
SCH_SELECTION & GetSelection()
SCH_SELECTION & RequestSelection(const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, bool aPromoteCellSelections=false, bool aPromoteGroups=false)
Return either an existing selection (filtered), or the selection at the current cursor position if th...
bool Selectable(const EDA_ITEM *aItem, const VECTOR2I *aPos=nullptr, bool checkVisibilityOnly=false) const
Check conditions for an item to be selected.
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:318
A foundation class for a tool operating on a schematic or symbol.
Definition: sch_tool_base.h:49
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
void saveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aType, bool aAppend=false, bool aDirtyConnectivity=true)
bool Init() override
Init() is called once upon a registration of the tool.
Definition: sch_tool_base.h:65
SCH_SELECTION_TOOL * m_selectionTool
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:80
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:126
ITER begin()
Definition: selection.h:79
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:92
bool IsHover() const
Definition: selection.h:89
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:105
EDA_ITEM * Front() const
Definition: selection.h:177
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:98
int Size() const
Returns the number of selected parts.
Definition: selection.h:121
std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:263
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:178
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:115
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:449
const std::string & GetString()
Definition: richio.h:472
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:86
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:44
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:38
Generic, UI-independent tool event.
Definition: tool_event.h:168
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:389
COMMIT * Commit() const
Definition: tool_event.h:280
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:465
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:37
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:57
#define _(s)
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:566
#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
@ LAYER_DEVICE
Definition: layer_ids.h:456
void Prettify(std::string &aSource, bool aCompactSave)
PIN_ORIENTATION
The symbol library pin object orientations.
Definition: pin_type.h:105
const std::vector< KICAD_T > swappableItems
wxString GetSelectedItemsAsText(const SELECTION &aSel)
wxString TitleCaps(const wxString &aString)
Capitalize the first letter in each word.
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:166
@ LIB_SYMBOL_T
Definition: typeinfo.h:149
@ SCH_TABLECELL_T
Definition: typeinfo.h:167
@ SCH_FIELD_T
Definition: typeinfo.h:151
@ SCH_SHAPE_T
Definition: typeinfo.h:150
@ SCH_TEXT_T
Definition: typeinfo.h:152
@ SCH_TEXTBOX_T
Definition: typeinfo.h:153
@ SCH_PIN_T
Definition: typeinfo.h:154
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:644