KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_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-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <kiway.h>
26#include <tool/picker_tool.h>
27#include <tools/sch_edit_tool.h>
30#include <tools/sch_move_tool.h>
32#include <confirm.h>
33#include <ee_actions.h>
34#include <ee_tool_utils.h>
35#include <increment.h>
36#include <string_utils.h>
37#include <sch_bitmap.h>
38#include <sch_bus_entry.h>
39#include <sch_commit.h>
40#include <sch_junction.h>
41#include <sch_marker.h>
42#include <sch_rule_area.h>
43#include <sch_sheet_pin.h>
44#include <sch_textbox.h>
45#include <sch_table.h>
47#include <eeschema_id.h>
58#include <dialogs/dialog_text_properties.h>
59#include <dialogs/dialog_tablecell_properties.h>
60#include <dialogs/dialog_table_properties.h>
61#include <pgm_base.h>
64#include <core/kicad_algo.h>
65#include <view/view_controls.h>
66#include <wx/textdlg.h>
68
69
71{
72public:
74 ACTION_MENU( true )
75 {
76 SetIcon( BITMAPS::component_select_unit );
77 SetTitle( _( "Symbol Unit" ) );
78 }
79
80protected:
81 ACTION_MENU* create() const override
82 {
83 return new SYMBOL_UNIT_MENU();
84 }
85
86private:
87 void update() override
88 {
90 EE_SELECTION& selection = selTool->GetSelection();
91 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
92
93 Clear();
94
95 wxCHECK( symbol, /* void */ );
96
97 const int unit = symbol->GetUnit();
98 const int nUnits = symbol->GetLibSymbolRef()->GetUnitCount();
99 const std::set<int> missingUnits = GetUnplacedUnitsForSymbol( *symbol );
100
101 for( int ii = 0; ii < nUnits; ii++ )
102 {
103 wxString unit_text;
104
105 if( symbol->GetLibSymbolRef()->HasUnitDisplayName( ii + 1 ) )
106 unit_text = symbol->GetLibSymbolRef()->GetUnitDisplayName( ii + 1 );
107 else
108 unit_text.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
109
110 if( missingUnits.count( ii + 1 ) == 0 )
111 unit_text += _( " (already placed)" );
112
113 wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, unit_text, wxEmptyString,
114 wxITEM_CHECK );
115
116 if( unit == ii + 1 )
117 item->Check( true );
118
119 // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_END
120 // See eeschema_id to modify this value.
122 break; // We have used all IDs for these submenus
123 }
124
125 {
126 AppendSeparator();
127
128 wxMenuItem* item = Add( EE_ACTIONS::placeNextSymbolUnit );
129 item->Enable( missingUnits.size() );
130 }
131 }
132};
133
134
136{
137public:
139 ACTION_MENU( true )
140 {
141 SetIcon( BITMAPS::component_select_alternate_shape );
142 SetTitle( _( "Body Style" ) );
143 }
144
145protected:
146 ACTION_MENU* create() const override
147 {
148 return new BODY_STYLE_MENU();
149 }
150
151private:
152 void update() override
153 {
155 EE_SELECTION& selection = selTool->GetSelection();
156 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
157 wxMenuItem* item;
158
159 Clear();
160
161 wxCHECK( symbol, /* void */ );
162
163 item = Append( ID_POPUP_SCH_SELECT_BASE, _( "Standard" ), wxEmptyString, wxITEM_CHECK );
164 item->Check( symbol->GetBodyStyle() == BODY_STYLE::BASE );
165
166 item = Append( ID_POPUP_SCH_SELECT_ALT, _( "Alternate" ), wxEmptyString, wxITEM_CHECK );
167 item->Check( symbol->GetBodyStyle() != BODY_STYLE::BASE );
168 }
169};
170
171
173{
174public:
176 ACTION_MENU( true )
177 {
178 SetIcon( BITMAPS::component_select_unit );
179 SetTitle( _( "Pin Function" ) );
180 }
181
182protected:
183 ACTION_MENU* create() const override
184 {
185 return new ALT_PIN_FUNCTION_MENU();
186 }
187
188private:
189 void update() override
190 {
192 EE_SELECTION& selection = selTool->GetSelection();
193 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
194 SCH_PIN* libPin = pin ? pin->GetLibPin() : nullptr;
195
196 Clear();
197
198 wxCHECK( libPin, /* void */ );
199
200 wxMenuItem* item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION, libPin->GetName(), wxEmptyString,
201 wxITEM_CHECK );
202
203 if( pin->GetAlt().IsEmpty() )
204 item->Check( true );
205
206 int ii = 1;
207
208 for( const auto& [ name, definition ] : libPin->GetAlternates() )
209 {
210 item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION + ii, name, wxEmptyString, wxITEM_CHECK );
211
212 if( name == pin->GetAlt() )
213 item->Check( true );
214
215 // The ID max for these submenus is ID_POPUP_SCH_ALT_PIN_FUNCTION_END
216 // See eeschema_id to modify this value.
218 break; // We have used all IDs for these submenus
219 }
220 }
221};
222
223
225{
226public:
228 {
229 SetIcon( BITMAPS::pin );
230 SetTitle( _( "Pin Helpers" ) );
231 }
232
233protected:
234 ACTION_MENU* create() const override { return new PIN_TRICKS_MENU(); }
235
236private:
237 void update() override
238 {
240 EE_SELECTION& selection = selTool->GetSelection();
241 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
242 SCH_SHEET_PIN* sheetPin = dynamic_cast<SCH_SHEET_PIN*>( selection.Front() );
243
244 Clear();
245
246 if( !pin && !sheetPin )
247 return;
248
249 Add( _( "Wire" ), ID_POPUP_SCH_PIN_TRICKS_WIRE, BITMAPS::add_line );
250 Add( _( "No Connect" ), ID_POPUP_SCH_PIN_TRICKS_NO_CONNECT, BITMAPS::noconn );
251 Add( _( "Net Label" ), ID_POPUP_SCH_PIN_TRICKS_NET_LABEL, BITMAPS::add_label );
252 Add( _( "Hierarchical Label" ), ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL, BITMAPS::add_hierarchical_label );
253 Add( _( "Global Label" ), ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL, BITMAPS::add_glabel );
254 }
255};
256
257
259 EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
260{
261 m_pickerItem = nullptr;
262}
263
264
266
268{
270
273
274 wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
275
276 auto hasElements =
277 [this]( const SELECTION& aSel )
278 {
279 return !m_frame->GetScreen()->Items().empty();
280 };
281
282 auto sheetHasUndefinedPins =
283 []( const SELECTION& aSel )
284 {
285 if( aSel.Size() == 1 && aSel.Front()->Type() == SCH_SHEET_T )
286 return static_cast<SCH_SHEET*>( aSel.Front() )->HasUndefinedPins();
287
288 return false;
289 };
290
291 static const std::vector<KICAD_T> sheetTypes = { SCH_SHEET_T };
292
293 auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( sheetTypes );
294
295 auto haveHighlight =
296 [&]( const SELECTION& sel )
297 {
298 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
299
300 return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
301 };
302
303 auto anyTextTool =
304 [this]( const SELECTION& aSel )
305 {
311 };
312
313 auto duplicateCondition =
314 []( const SELECTION& aSel )
315 {
317 return false;
318
319 return true;
320 };
321
322 auto orientCondition =
323 []( const SELECTION& aSel )
324 {
326 return false;
327
329 };
330
331 auto propertiesCondition =
332 [&]( const SELECTION& aSel )
333 {
334 if( aSel.GetSize() == 0 )
335 {
337 {
340
341 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
342 return true;
343 }
344
345 return false;
346 }
347
348 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
349 const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
350
351 if( !firstItem || !eeSelection )
352 return false;
353
354 switch( firstItem->Type() )
355 {
356 case SCH_SYMBOL_T:
357 case SCH_SHEET_T:
358 case SCH_SHEET_PIN_T:
359 case SCH_TEXT_T:
360 case SCH_TEXTBOX_T:
361 case SCH_TABLE_T:
362 case SCH_TABLECELL_T:
363 case SCH_LABEL_T:
365 case SCH_HIER_LABEL_T:
367 case SCH_RULE_AREA_T:
368 case SCH_FIELD_T:
369 case SCH_SHAPE_T:
370 case SCH_BITMAP_T:
371 return aSel.GetSize() == 1;
372
373 case SCH_LINE_T:
375 case SCH_JUNCTION_T:
376 if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
377 [&]( const EDA_ITEM* item )
378 {
379 return item->Type() == SCH_LINE_T
380 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
381 } ) )
382 {
383 return true;
384 }
385 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
386 [&]( const EDA_ITEM* item )
387 {
388 return item->Type() == SCH_JUNCTION_T;
389 } ) )
390 {
391 return true;
392 }
393 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
394 [&]( const EDA_ITEM* item )
395 {
396 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
397
398 wxCHECK( schItem, false );
399
400 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
401 || item->Type() == SCH_JUNCTION_T;
402 } ) )
403 {
404 return true;
405 }
406
407 return false;
408
409 default:
410 return false;
411 }
412 };
413
414 auto autoplaceCondition =
415 []( const SELECTION& aSel )
416 {
417 for( const EDA_ITEM* item : aSel )
418 {
419 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
420 return true;
421 }
422
423 return false;
424 };
425
426 // allTextTypes does not include SCH_SHEET_PIN_T because one cannot convert other
427 // types to/from this type, living only in a SHEET
428 static const std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
434
435 auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
436
437 static const std::vector<KICAD_T> toLabelTypes = { SCH_DIRECTIVE_LABEL_T,
442
443 auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toLabelTypes ) )
444 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
445
446 static const std::vector<KICAD_T> toCLabelTypes = { SCH_LABEL_T,
451
452 auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toCLabelTypes ) )
453 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
454
455 static const std::vector<KICAD_T> toHLabelTypes = { SCH_LABEL_T,
460
461 auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toHLabelTypes ) )
462 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
463
464 static const std::vector<KICAD_T> toGLabelTypes = { SCH_LABEL_T,
469
470 auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toGLabelTypes ) )
471 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
472
473 static const std::vector<KICAD_T> toTextTypes = { SCH_LABEL_T,
478
479 auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toTextTypes ) )
480 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
481
482 static const std::vector<KICAD_T> toTextBoxTypes = { SCH_LABEL_T,
486 SCH_TEXT_T };
487
488 auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toTextBoxTypes ) )
489 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
490
491 static const std::vector<KICAD_T> busEntryTypes = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T};
492
493 auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( busEntryTypes );
494
495 auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( sheetTypes );
496
497 auto makeSymbolUnitMenu =
498 [&]( TOOL_INTERACTIVE* tool )
499 {
500 std::shared_ptr<SYMBOL_UNIT_MENU> menu = std::make_shared<SYMBOL_UNIT_MENU>();
501 menu->SetTool( tool );
502 tool->GetToolMenu().RegisterSubMenu( menu );
503 return menu.get();
504 };
505
506 auto makeBodyStyleMenu =
507 [&]( TOOL_INTERACTIVE* tool )
508 {
509 std::shared_ptr<BODY_STYLE_MENU> menu = std::make_shared<BODY_STYLE_MENU>();
510 menu->SetTool( tool );
511 tool->GetToolMenu().RegisterSubMenu( menu );
512 return menu.get();
513 };
514
515 auto makePinFunctionMenu =
516 [&]( TOOL_INTERACTIVE* tool )
517 {
518 std::shared_ptr<ALT_PIN_FUNCTION_MENU> menu = std::make_shared<ALT_PIN_FUNCTION_MENU>();
519 menu->SetTool( tool );
520 tool->GetToolMenu().RegisterSubMenu( menu );
521 return menu.get();
522 };
523
524 auto makePinTricksMenu =
525 [&]( TOOL_INTERACTIVE* tool )
526 {
527 std::shared_ptr<PIN_TRICKS_MENU> menu = std::make_shared<PIN_TRICKS_MENU>();
528 menu->SetTool( tool );
529 tool->GetToolMenu().RegisterSubMenu( menu );
530 return menu.get();
531 };
532
533 auto makeTransformMenu =
534 [&]()
535 {
536 CONDITIONAL_MENU* menu = new CONDITIONAL_MENU( moveTool );
537 menu->SetTitle( _( "Transform Selection" ) );
538
539 menu->AddItem( EE_ACTIONS::rotateCCW, orientCondition );
540 menu->AddItem( EE_ACTIONS::rotateCW, orientCondition );
541 menu->AddItem( EE_ACTIONS::mirrorV, orientCondition );
542 menu->AddItem( EE_ACTIONS::mirrorH, orientCondition );
543
544 return menu;
545 };
546
547 auto makeAttributesMenu =
548 [&]()
549 {
550 CONDITIONAL_MENU* menu = new CONDITIONAL_MENU( moveTool );
551 menu->SetTitle( _( "Attributes" ) );
552
556
557 menu->AddSeparator();
561
562 menu->AddSeparator();
566
567 menu->AddSeparator();
571
572 return menu;
573 };
574
575 auto makeEditFieldsMenu =
576 [&]()
577 {
579 menu->SetTitle( _( "Edit Main Fields" ) );
580
584
585 return menu;
586 };
587
588 auto makeConvertToMenu =
589 [&]()
590 {
592 menu->SetTitle( _( "Change To" ) );
593 menu->SetIcon( BITMAPS::right );
594
595 menu->AddItem( EE_ACTIONS::toLabel, toLabelCondition );
596 menu->AddItem( EE_ACTIONS::toCLabel, toCLabelCondition );
597 menu->AddItem( EE_ACTIONS::toHLabel, toHLabelCondition );
598 menu->AddItem( EE_ACTIONS::toGLabel, toGLabelCondition );
599 menu->AddItem( EE_ACTIONS::toText, toTextCondition );
600 menu->AddItem( EE_ACTIONS::toTextBox, toTextBoxCondition );
601
602 return menu;
603 };
604
605 const auto canCopyText = EE_CONDITIONS::OnlyTypes( {
614 SCH_PIN_T,
617 } );
618
619 //
620 // Add edit actions to the move tool menu
621 //
622 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
623
624 moveMenu.AddSeparator();
625 moveMenu.AddMenu( makeSymbolUnitMenu( moveTool ), E_C::SingleMultiUnitSymbol, 1 );
626 moveMenu.AddMenu( makeBodyStyleMenu( moveTool ), E_C::SingleDeMorganSymbol, 1 );
627
628 moveMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
629 moveMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
630 moveMenu.AddItem( EE_ACTIONS::swap, SELECTION_CONDITIONS::MoreThan( 1 ), 200);
631 moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
632 moveMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
633
634 moveMenu.AddSeparator();
635 moveMenu.AddItem( ACTIONS::cut, E_C::IdleSelection );
636 moveMenu.AddItem( ACTIONS::copy, E_C::IdleSelection );
637 moveMenu.AddItem( ACTIONS::copyAsText, canCopyText && E_C::IdleSelection );
638 moveMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty );
639 moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
640
641 //
642 // Add editing actions to the drawing tool menu
643 //
644 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
645
646 drawMenu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
647 drawMenu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
648
649 drawMenu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
650 drawMenu.AddSeparator( sheetSelection && EE_CONDITIONS::Idle, 1 );
651
652 drawMenu.AddMenu( makeSymbolUnitMenu( drawingTools ), E_C::SingleMultiUnitSymbol, 1 );
653 drawMenu.AddMenu( makeBodyStyleMenu( drawingTools ), E_C::SingleDeMorganSymbol, 1 );
654
655 drawMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
656 drawMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
657 drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
658 drawMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
659 drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
660
662
663 drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
664 drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
665 drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
666 drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
667 drawMenu.AddItem( EE_ACTIONS::toTextBox, anyTextTool && E_C::Idle, 200 );
668
669 //
670 // Add editing actions to the selection tool menu
671 //
673
674 selToolMenu.AddMenu( makeSymbolUnitMenu( m_selectionTool ), E_C::SingleMultiUnitSymbol, 1 );
675 selToolMenu.AddMenu( makeBodyStyleMenu( m_selectionTool ), E_C::SingleDeMorganSymbol, 1 );
676 selToolMenu.AddMenu( makePinFunctionMenu( m_selectionTool ), E_C::SingleMultiFunctionPin, 1 );
677 selToolMenu.AddMenu( makePinTricksMenu( m_selectionTool ), E_C::AllPinsOrSheetPins, 1 );
678
679 selToolMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
680 selToolMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
682 selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
683 selToolMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
684 selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
685
691 selToolMenu.AddMenu( makeConvertToMenu(), toChangeCondition, 200 );
692
693 selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
694
695 selToolMenu.AddSeparator( 300 );
696 selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
697 selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
698 selToolMenu.AddItem( ACTIONS::copyAsText, canCopyText && E_C::IdleSelection, 300 );
699 selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
700 selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
701 selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
702 selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
703
704 selToolMenu.AddSeparator( 400 );
705 selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
706 selToolMenu.AddItem( ACTIONS::unselectAll, hasElements, 400 );
707
708 return true;
709}
710
711
712const std::vector<KICAD_T> SCH_EDIT_TOOL::RotatableItems = {
718 SCH_TABLECELL_T, // will be promoted to parent table(s)
733};
734
735
737{
738 bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
740
741 if( selection.GetSize() == 0 )
742 return 0;
743
744 SCH_ITEM* head = nullptr;
745 int principalItemCount = 0; // User-selected items (as opposed to connected wires)
746 VECTOR2I rotPoint;
747 bool moving = false;
748 SCH_COMMIT localCommit( m_toolMgr );
749 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
750
751 if( !commit )
752 commit = &localCommit;
753
754 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
755 {
756 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
757
758 if( item->HasFlag( SELECTED_BY_DRAG ) )
759 continue;
760
761 principalItemCount++;
762
763 if( !head )
764 head = item;
765 }
766
767 if( head && head->IsMoving() )
768 moving = true;
769
770 if( principalItemCount == 1 )
771 {
772 if( moving && selection.HasReferencePoint() )
773 rotPoint = selection.GetReferencePoint();
774 else if( head->IsConnectable() )
775 rotPoint = head->GetPosition();
776 else
778
779 if( !moving )
780 commit->Modify( head, m_frame->GetScreen() );
781
782 switch( head->Type() )
783 {
784 case SCH_SYMBOL_T:
785 {
786 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
787
788 symbol->Rotate( rotPoint, !clockwise );
789
792
793 break;
794 }
795
796 case SCH_TEXT_T:
797 case SCH_LABEL_T:
799 case SCH_HIER_LABEL_T:
801 {
802 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
803 textItem->Rotate90( clockwise );
804 break;
805 }
806
807 case SCH_SHEET_PIN_T:
808 {
809 // Rotate pin within parent sheet
810 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
811 SCH_SHEET* sheet = pin->GetParent();
812
813 pin->Rotate( sheet->GetBoundingBox().GetCenter(), !clockwise );
814
815 break;
816 }
817
818 case SCH_LINE_T:
819 {
820 SCH_LINE* line = static_cast<SCH_LINE*>( head );
821
822 // Equal checks for both and neither. We need this because on undo
823 // the item will have both flags cleared, but will be selected, so it is possible
824 // for the user to get a selected line with neither endpoint selected. We
825 // set flags to make sure Rotate() works when we call it.
826 if( line->HasFlag( STARTPOINT ) == line->HasFlag( ENDPOINT ) )
827 {
828 line->SetFlags( STARTPOINT | ENDPOINT );
829
830 // When we allow off grid items, the rotPoint should be set to the midpoint
831 // of the line to allow rotation around the center, and the next if
832 // should become an else-if
833 }
834
835 if( line->HasFlag( STARTPOINT ) )
836 rotPoint = line->GetEndPoint();
837 else if( line->HasFlag( ENDPOINT ) )
838 rotPoint = line->GetStartPoint();
839 }
840
842 case SCH_JUNCTION_T:
843 case SCH_NO_CONNECT_T:
846 head->Rotate( rotPoint, !clockwise );
847
848 break;
849
850 case SCH_FIELD_T:
851 {
852 SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
853
854 if( field->GetTextAngle().IsHorizontal() )
856 else
858
859 // Now that we're moving a field, they're no longer autoplaced.
860 static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
861
862 break;
863 }
864
865 case SCH_RULE_AREA_T:
866 case SCH_SHAPE_T:
867 case SCH_TEXTBOX_T:
868 head->Rotate( rotPoint, !clockwise );
869
870 break;
871
872 case SCH_TABLE_T:
873 {
874 // Rotate the table on itself. Tables do not have an anchor point.
875 SCH_TABLE* table = static_cast<SCH_TABLE*>( head );
876 BOX2I box( table->GetPosition(), table->GetEnd() - table->GetPosition() );
877 rotPoint = m_frame->GetNearestHalfGridPosition( box.GetCenter() );
878
879 head->Rotate( rotPoint, !clockwise );
880
881 break;
882 }
883
884 case SCH_BITMAP_T:
885 head->Rotate( rotPoint, !clockwise );
886
887 // The bitmap is cached in Opengl: clear the cache to redraw
889 break;
890
891 case SCH_SHEET_T:
892 {
893 // Rotate the sheet on itself. Sheets do not have an anchor point.
894 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
895
897 sheet->Rotate( rotPoint, !clockwise );
898
899 break;
900 }
901
902 default:
903 UNIMPLEMENTED_FOR( head->GetClass() );
904 }
905
906 m_frame->UpdateItem( head, false, true );
907 }
908 else
909 {
910 if( moving && selection.HasReferencePoint() )
911 rotPoint = selection.GetReferencePoint();
912 else
913 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
914 }
915
916 for( EDA_ITEM* edaItem : selection )
917 {
918 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
919
920 // We've already rotated the user selected item if there was only one. We're just
921 // here to rotate the ends of wires that were attached to it.
922 if( principalItemCount == 1 && !item->HasFlag( SELECTED_BY_DRAG ) )
923 continue;
924
925 if( !moving )
926 commit->Modify( item, m_frame->GetScreen() );
927
928 if( item->Type() == SCH_LINE_T )
929 {
930 SCH_LINE* line = (SCH_LINE*) item;
931
932 line->Rotate( rotPoint, !clockwise );
933 }
934 else if( item->Type() == SCH_SHEET_PIN_T )
935 {
936 if( item->GetParent()->IsSelected() )
937 {
938 // parent will rotate us
939 }
940 else
941 {
942 // rotate within parent
943 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
944 SCH_SHEET* sheet = pin->GetParent();
945
946 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter(), !clockwise );
947 }
948 }
949 else if( item->Type() == SCH_FIELD_T )
950 {
951 if( item->GetParent()->IsSelected() )
952 {
953 // parent will rotate us
954 }
955 else
956 {
957 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
958
959 field->Rotate( rotPoint, !clockwise );
960
961 if( field->GetTextAngle().IsHorizontal() )
963 else
965
966 // Now that we're moving a field, they're no longer autoplaced.
967 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
968 }
969 }
970 else
971 {
972 item->Rotate( rotPoint, !clockwise );
973 }
974
975 m_frame->UpdateItem( item, false, true );
976 updateItem( item, true );
977 }
978
979 if( moving )
980 {
982 }
983 else
984 {
985 EE_SELECTION selectionCopy = selection;
986
987 if( selection.IsHover() )
989
991 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
992 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
993
994 m_frame->SchematicCleanUp( commit );
995
996 if( !localCommit.Empty() )
997 localCommit.Push( _( "Rotate" ) );
998 }
999
1000 return 0;
1001}
1002
1003
1005{
1007
1008 if( selection.GetSize() == 0 )
1009 return 0;
1010
1011 bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
1012 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
1013 bool connections = false;
1014 bool moving = item->IsMoving();
1015 SCH_COMMIT localCommit( m_toolMgr );
1016 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
1017
1018 if( !commit )
1019 commit = &localCommit;
1020
1021 if( selection.GetSize() == 1 )
1022 {
1023 if( !moving )
1024 commit->Modify( item, m_frame->GetScreen() );
1025
1026 switch( item->Type() )
1027 {
1028 case SCH_SYMBOL_T:
1029 {
1030 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1031
1032 if( vertical )
1033 symbol->SetOrientation( SYM_MIRROR_X );
1034 else
1035 symbol->SetOrientation( SYM_MIRROR_Y );
1036
1037 symbol->ClearFieldsAutoplaced();
1038 break;
1039 }
1040
1041 case SCH_TEXT_T:
1042 case SCH_LABEL_T:
1043 case SCH_GLOBAL_LABEL_T:
1044 case SCH_HIER_LABEL_T:
1046 {
1047 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
1048 textItem->MirrorSpinStyle( !vertical );
1049 break;
1050 }
1051
1052 case SCH_SHEET_PIN_T:
1053 {
1054 // mirror within parent sheet
1055 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1056 SCH_SHEET* sheet = pin->GetParent();
1057
1058 if( vertical )
1059 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
1060 else
1061 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
1062
1063 break;
1064 }
1065
1066 case SCH_FIELD_T:
1067 {
1068 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1069
1070 if( vertical )
1072 else
1074
1075 // Now that we're re-justifying a field, they're no longer autoplaced.
1076 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1077
1078 break;
1079 }
1080
1081 case SCH_BITMAP_T:
1082 if( vertical )
1083 item->MirrorVertically( item->GetPosition().y );
1084 else
1085 item->MirrorHorizontally( item->GetPosition().x );
1086
1087 // The bitmap is cached in Opengl: clear the cache to redraw
1089 break;
1090
1091 case SCH_SHEET_T:
1092 {
1093 // Mirror the sheet on itself. Sheets do not have a anchor point.
1095
1096 if( vertical )
1097 item->MirrorVertically( mirrorPoint.y );
1098 else
1099 item->MirrorHorizontally( mirrorPoint.x );
1100
1101 break;
1102 }
1103
1104 default:
1105 if( vertical )
1106 item->MirrorVertically( item->GetPosition().y );
1107 else
1108 item->MirrorHorizontally( item->GetPosition().x );
1109
1110 break;
1111 }
1112
1113 connections = item->IsConnectable();
1114 m_frame->UpdateItem( item, false, true );
1115 }
1116 else if( selection.GetSize() > 1 )
1117 {
1118 VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
1119
1120 for( EDA_ITEM* edaItem : selection )
1121 {
1122 item = static_cast<SCH_ITEM*>( edaItem );
1123
1124 if( !moving )
1125 commit->Modify( item, m_frame->GetScreen() );
1126
1127 if( item->Type() == SCH_SHEET_PIN_T )
1128 {
1129 if( item->GetParent()->IsSelected() )
1130 {
1131 // parent will mirror us
1132 }
1133 else
1134 {
1135 // mirror within parent sheet
1136 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1137 SCH_SHEET* sheet = pin->GetParent();
1138
1139 if( vertical )
1140 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
1141 else
1142 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
1143 }
1144 }
1145 else if( item->Type() == SCH_FIELD_T )
1146 {
1147 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1148
1149 if( vertical )
1151 else
1153
1154 // Now that we're re-justifying a field, they're no longer autoplaced.
1155 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1156 }
1157 else
1158 {
1159 if( vertical )
1160 item->MirrorVertically( mirrorPoint.y );
1161 else
1162 item->MirrorHorizontally( mirrorPoint.x );
1163 }
1164
1165 connections |= item->IsConnectable();
1166 m_frame->UpdateItem( item, false, true );
1167 }
1168 }
1169
1170 // Update R-Tree for modified items
1171 for( EDA_ITEM* selected : selection )
1172 updateItem( selected, true );
1173
1174 if( item->IsMoving() )
1175 {
1177 }
1178 else
1179 {
1180 EE_SELECTION selectionCopy = selection;
1181
1182 if( selection.IsHover() )
1184
1185 if( connections )
1186 {
1188 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
1189 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
1190
1191 m_frame->SchematicCleanUp( commit );
1192 }
1193
1194 if( !localCommit.Empty() )
1195 localCommit.Push( _( "Mirror" ) );
1196 }
1197
1198 return 0;
1199}
1200
1201
1202const std::vector<KICAD_T> swappableItems = {
1205 SCH_TEXT_T,
1218};
1219
1220
1231static void swapFieldPositionsWithMatching( std::vector<SCH_FIELD>& aAFields,
1232 std::vector<SCH_FIELD>& aBFields,
1233 unsigned aFallbackRotationsCCW )
1234{
1235 std::set<wxString> handledKeys;
1236
1237 const auto swapFieldTextProps = []( SCH_FIELD& aField, SCH_FIELD& bField )
1238 {
1239 const VECTOR2I aRelPos = aField.GetPosition() - aField.GetParentPosition();
1240 const GR_TEXT_H_ALIGN_T aTextJustifyH = aField.GetHorizJustify();
1241 const GR_TEXT_V_ALIGN_T aTextJustifyV = aField.GetVertJustify();
1242 const EDA_ANGLE aTextAngle = aField.GetTextAngle();
1243
1244 const VECTOR2I bRelPos = bField.GetPosition() - bField.GetParentPosition();
1245 const GR_TEXT_H_ALIGN_T bTextJustifyH = bField.GetHorizJustify();
1246 const GR_TEXT_V_ALIGN_T bTextJustifyV = bField.GetVertJustify();
1247 const EDA_ANGLE bTextAngle = bField.GetTextAngle();
1248
1249 aField.SetPosition( aField.GetParentPosition() + bRelPos );
1250 aField.SetHorizJustify( bTextJustifyH );
1251 aField.SetVertJustify( bTextJustifyV );
1252 aField.SetTextAngle( bTextAngle );
1253
1254 bField.SetPosition( bField.GetParentPosition() + aRelPos );
1255 bField.SetHorizJustify( aTextJustifyH );
1256 bField.SetVertJustify( aTextJustifyV );
1257 bField.SetTextAngle( aTextAngle );
1258 };
1259
1260 for( SCH_FIELD& aField : aAFields )
1261 {
1262 const wxString name = aField.GetCanonicalName();
1263
1264 auto it = std::find_if( aBFields.begin(), aBFields.end(),
1265 [name]( const SCH_FIELD& bField )
1266 {
1267 return bField.GetCanonicalName() == name;
1268 } );
1269
1270 if( it != aBFields.end() )
1271 {
1272 // We have a field with the same key in both labels
1273 SCH_FIELD& bField = *it;
1274 swapFieldTextProps( aField, bField );
1275 }
1276 else
1277 {
1278 // We only have this field in A, so just rotate it
1279 for( unsigned ii = 0; ii < aFallbackRotationsCCW; ii++ )
1280 {
1281 aField.Rotate( aField.GetParentPosition(), true );
1282 }
1283 }
1284
1285 // And keep track that we did this one
1286 handledKeys.insert( name );
1287 }
1288
1289 // Any fields in B that weren't in A weren't handled and need to be rotated
1290 // in reverse
1291 for( SCH_FIELD& bField : aBFields )
1292 {
1293 const wxString bName = bField.GetCanonicalName();
1294 if( handledKeys.find( bName ) == handledKeys.end() )
1295 {
1296 for( unsigned ii = 0; ii < aFallbackRotationsCCW; ii++ )
1297 {
1298 bField.Rotate( bField.GetParentPosition(), false );
1299 }
1300 }
1301 }
1302}
1303
1304
1306{
1308 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
1309
1310 // Sheet pins are special, we need to make sure if we have any sheet pins,
1311 // that we only have sheet pins, and that they have the same parent
1312 if( selection.CountType( SCH_SHEET_PIN_T ) > 0 )
1313 {
1314 if( !selection.OnlyContains( { SCH_SHEET_PIN_T } ) )
1315 return 0;
1316
1317 SCH_SHEET_PIN* firstPin = static_cast<SCH_SHEET_PIN*>( selection.Front() );
1318 SCH_SHEET* parent = firstPin->GetParent();
1319
1320 for( EDA_ITEM* item : selection )
1321 {
1322 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1323
1324 if( pin->GetParent() != parent )
1325 return 0;
1326 }
1327 }
1328
1329 if( selection.Size() < 2 )
1330 return 0;
1331
1332 bool isMoving = selection.Front()->IsMoving();
1333 bool appendUndo = isMoving;
1334 bool connections = false;
1335
1336 for( size_t i = 0; i < sorted.size() - 1; i++ )
1337 {
1338 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
1339 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
1340
1341 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
1342 std::swap( aPos, bPos );
1343
1344 saveCopyInUndoList( a, UNDO_REDO::CHANGED, appendUndo );
1345 appendUndo = true;
1346 saveCopyInUndoList( b, UNDO_REDO::CHANGED, appendUndo );
1347
1348 // Sheet pins need to have their sides swapped before we change their
1349 // positions
1350 if( a->Type() == SCH_SHEET_PIN_T )
1351 {
1352 SCH_SHEET_PIN* aPin = static_cast<SCH_SHEET_PIN*>( a );
1353 SCH_SHEET_PIN* bPin = static_cast<SCH_SHEET_PIN*>( b );
1354 SHEET_SIDE aSide = aPin->GetSide(), bSide = bPin->GetSide();
1355 std::swap( aSide, bSide );
1356 aPin->SetSide( aSide );
1357 bPin->SetSide( bSide );
1358 }
1359
1360 a->SetPosition( aPos );
1361 b->SetPosition( bPos );
1362
1363 if( a->Type() == b->Type() )
1364 {
1365 switch( a->Type() )
1366 {
1367 case SCH_LABEL_T:
1368 case SCH_GLOBAL_LABEL_T:
1369 case SCH_HIER_LABEL_T:
1371 {
1372 SCH_LABEL_BASE& aLabelBase = static_cast<SCH_LABEL_BASE&>( *a );
1373 SCH_LABEL_BASE& bLabelBase = static_cast<SCH_LABEL_BASE&>( *b );
1374
1375 const SPIN_STYLE aSpinStyle = aLabelBase.GetSpinStyle();
1376 const SPIN_STYLE bSpinStyle = bLabelBase.GetSpinStyle();
1377
1378 // First, swap the label orientations
1379 aLabelBase.SetSpinStyle( bSpinStyle );
1380 bLabelBase.SetSpinStyle( aSpinStyle );
1381
1382 // And swap the fields as best we can
1383 std::vector<SCH_FIELD>& aFields = aLabelBase.GetFields();
1384 std::vector<SCH_FIELD>& bFields = bLabelBase.GetFields();
1385
1386 const unsigned rotationsAtoB = aSpinStyle.CCWRotationsTo( bSpinStyle );
1387
1388 swapFieldPositionsWithMatching( aFields, bFields, rotationsAtoB );
1389 break;
1390 }
1391 case SCH_SYMBOL_T:
1392 {
1393 SCH_SYMBOL* aSymbol = static_cast<SCH_SYMBOL*>( a );
1394 SCH_SYMBOL* bSymbol = static_cast<SCH_SYMBOL*>( b );
1395 int aOrient = aSymbol->GetOrientation(), bOrient = bSymbol->GetOrientation();
1396 std::swap( aOrient, bOrient );
1397 aSymbol->SetOrientation( aOrient );
1398 bSymbol->SetOrientation( bOrient );
1399 break;
1400 }
1401 default: break;
1402 }
1403 }
1404
1405 connections |= a->IsConnectable();
1406 connections |= b->IsConnectable();
1407 m_frame->UpdateItem( a, false, true );
1408 m_frame->UpdateItem( b, false, true );
1409 }
1410
1411 // Update R-Tree for modified items
1412 for( EDA_ITEM* selected : selection )
1413 updateItem( selected, true );
1414
1415 if( isMoving )
1416 {
1418 }
1419 else
1420 {
1421 if( selection.IsHover() )
1423
1424 if( connections )
1426
1427 m_frame->OnModify();
1428 }
1429
1430 return 0;
1431}
1432
1433
1435{
1436 const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
1437
1438 if( sourceItems.empty() )
1439 return 0;
1440
1442
1443 SCH_COMMIT commit( m_toolMgr );
1444 EE_SELECTION newItems;
1445
1446 for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
1447 {
1448 SCH_ITEM* newItem = item->Duplicate();
1450 bool restore_state = false;
1451
1452 // Ensure newItem has a suitable parent: the current screen, because an item from
1453 // a list of items to repeat must be attached to this current screen
1454 newItem->SetParent( m_frame->GetScreen() );
1455
1456 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
1457 {
1458 // If incrementing tries to go below zero, tell user why the value is repeated
1459
1460 if( !label->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
1461 m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
1462 }
1463
1464 // If cloning a symbol then put into 'move' mode.
1465 if( newItem->Type() == SCH_SYMBOL_T )
1466 {
1467 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
1468 newItem->Move( cursorPos - newItem->GetPosition() );
1469 }
1470 else
1471 {
1474 }
1475
1476 // If cloning a sheet, check that we aren't going to create recursion
1477 if( newItem->Type() == SCH_SHEET_T )
1478 {
1479 SCH_SHEET_PATH* currentSheet = &m_frame->GetCurrentSheet();
1480 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( newItem );
1481
1482 if( m_frame->CheckSheetForRecursion( sheet, currentSheet ) )
1483 {
1484 // Clear out the filename so that the user can pick a new one
1485 const wxString originalFileName = sheet->GetFileName();
1486 const wxString originalScreenFileName = sheet->GetScreen()->GetFileName();
1487
1488 sheet->SetFileName( wxEmptyString );
1489 sheet->GetScreen()->SetFileName( wxEmptyString );
1490 restore_state = !m_frame->EditSheetProperties( sheet, currentSheet );
1491
1492 if( restore_state )
1493 {
1494 sheet->SetFileName( originalFileName );
1495 sheet->GetScreen()->SetFileName( originalScreenFileName );
1496 }
1497 }
1498 }
1499
1501 newItem->SetFlags( IS_NEW );
1502 m_frame->AddToScreen( newItem, m_frame->GetScreen() );
1503 commit.Added( newItem, m_frame->GetScreen() );
1504
1505 if( newItem->Type() == SCH_SYMBOL_T )
1506 {
1508 SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
1509 int annotateStartNum = projSettings.m_AnnotateStartNum;
1510
1511 if( annotate.automatic )
1512 {
1513 static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
1514 NULL_REPORTER reporter;
1516 (ANNOTATE_ORDER_T) annotate.sort_order,
1517 (ANNOTATE_ALGO_T) annotate.method, true /* recursive */,
1518 annotateStartNum, false, false, reporter );
1519 }
1520
1521 // Annotation clears the selection so re-add the item
1523
1524 restore_state = !m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit );
1525 }
1526
1527 if( restore_state )
1528 {
1529 commit.Revert();
1530 }
1531 else
1532 {
1533 newItems.Add( newItem );
1534
1536 lwbTool->TrimOverLappingWires( &commit, &newItems );
1537 lwbTool->AddJunctionsIfNeeded( &commit, &newItems );
1538
1539 m_frame->SchematicCleanUp( &commit );
1540 commit.Push( _( "Repeat Item" ) );
1541 }
1542
1543 }
1544
1545 if( !newItems.Empty() )
1546 m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
1547
1548 for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
1549 m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
1550
1551 return 0;
1552}
1553
1554
1555static std::vector<KICAD_T> deletableItems =
1556{
1559 SCH_LINE_T,
1564 SCH_TEXT_T,
1566 SCH_TABLECELL_T, // Clear contents
1576 SCH_FIELD_T, // Will be hidden
1578};
1579
1580
1582{
1583 SCH_SCREEN* screen = m_frame->GetScreen();
1584 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection( deletableItems ).GetItems();
1585 SCH_COMMIT commit( m_toolMgr );
1586 std::vector<VECTOR2I> pts;
1587 bool updateHierarchy = false;
1588
1589 if( items.empty() )
1590 return 0;
1591
1592 // Don't leave a freed pointer in the selection
1594
1595 for( EDA_ITEM* item : items )
1596 item->ClearFlags( STRUCT_DELETED );
1597
1598 for( EDA_ITEM* item : items )
1599 {
1600 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1601
1602 if( !sch_item )
1603 continue;
1604
1605 if( sch_item->IsConnectable() )
1606 {
1607 std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
1608 pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1609 }
1610
1611 if( sch_item->Type() == SCH_JUNCTION_T )
1612 {
1613 sch_item->SetFlags( STRUCT_DELETED );
1614 // clean up junctions at the end
1615 }
1616 else if( sch_item->Type() == SCH_SHEET_PIN_T )
1617 {
1618 SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1619 SCH_SHEET* sheet = pin->GetParent();
1620
1621 if( !alg::contains( items, sheet ) )
1622 {
1623 commit.Modify( sheet, m_frame->GetScreen() );
1624 sheet->RemovePin( pin );
1625 }
1626 }
1627 else if( sch_item->Type() == SCH_FIELD_T )
1628 {
1629 // Hide field
1630 commit.Modify( item, m_frame->GetScreen() );
1631 static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
1632 }
1633 else if( sch_item->Type() == SCH_TABLECELL_T )
1634 {
1635 // Clear contents of table cell
1636 commit.Modify( item, m_frame->GetScreen() );
1637 static_cast<SCH_TABLECELL*>( sch_item )->SetText( wxEmptyString );
1638 }
1639 else if( sch_item->Type() == SCH_RULE_AREA_T )
1640 {
1641 sch_item->SetFlags( STRUCT_DELETED );
1642 commit.Remove( item, m_frame->GetScreen() );
1643 }
1644 else
1645 {
1646 sch_item->SetFlags( STRUCT_DELETED );
1647 commit.Remove( item, m_frame->GetScreen() );
1648 updateHierarchy |= ( sch_item->Type() == SCH_SHEET_T );
1649 }
1650 }
1651
1652 for( const VECTOR2I& point : pts )
1653 {
1654 SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1655
1656 if( !junction )
1657 continue;
1658
1659 if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1660 m_frame->DeleteJunction( &commit, junction );
1661 }
1662
1663 commit.Push( _( "Delete" ) );
1664
1665 if( updateHierarchy )
1667
1668 return 0;
1669}
1670
1671
1672#define HITTEST_THRESHOLD_PIXELS 5
1673
1674
1676{
1678
1680 m_pickerItem = nullptr;
1681
1682 // Deactivate other tools; particularly important if another PICKER is currently running
1683 Activate();
1684
1685 picker->SetCursor( KICURSOR::REMOVE );
1686 picker->SetSnapping( false );
1687
1688 picker->SetClickHandler(
1689 [this]( const VECTOR2D& aPosition ) -> bool
1690 {
1691 if( m_pickerItem )
1692 {
1694 selectionTool->UnbrightenItem( m_pickerItem );
1695 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1697 m_pickerItem = nullptr;
1698 }
1699
1700 return true;
1701 } );
1702
1703 picker->SetMotionHandler(
1704 [this]( const VECTOR2D& aPos )
1705 {
1706 EE_COLLECTOR collector;
1707 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1708 collector.Collect( m_frame->GetScreen(), deletableItems, aPos );
1709
1711 selectionTool->GuessSelectionCandidates( collector, aPos );
1712
1713 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1714
1715 if( m_pickerItem != item )
1716 {
1717 if( m_pickerItem )
1718 selectionTool->UnbrightenItem( m_pickerItem );
1719
1720 m_pickerItem = item;
1721
1722 if( m_pickerItem )
1723 selectionTool->BrightenItem( m_pickerItem );
1724 }
1725 } );
1726
1727 picker->SetFinalizeHandler(
1728 [this]( const int& aFinalState )
1729 {
1730 if( m_pickerItem )
1731 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
1732
1733 // Wake the selection tool after exiting to ensure the cursor gets updated
1735 } );
1736
1738
1739 return 0;
1740}
1741
1742
1744{
1745 KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1746 SCH_COMMIT commit( m_toolMgr );
1747
1748 // Save old symbol in undo list if not already in edit, or moving.
1749 if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1750 commit.Modify( aField, m_frame->GetScreen() );
1751
1752 if( parentType == SCH_SYMBOL_T && aField->GetId() == REFERENCE_FIELD )
1753 static_cast<SCH_ITEM*>( aField->GetParent() )->SetConnectivityDirty();
1754
1755 wxString caption;
1756
1757 // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1758 if( parentType == SCH_SYMBOL_T && aField->IsMandatory() )
1759 {
1760 wxString translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(),
1761 DO_TRANSLATE );
1762 caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
1763 }
1764 else if( parentType == SCH_SHEET_T && aField->IsMandatory() )
1765 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1766 else
1767 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1768
1769 DIALOG_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1770
1771 // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1772 if( dlg.ShowQuasiModal() != wxID_OK )
1773 return;
1774
1775 dlg.UpdateField( &commit, aField, &m_frame->GetCurrentSheet() );
1776
1777 if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1778 static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1779
1780 if( !commit.Empty() )
1781 commit.Push( caption );
1782}
1783
1784
1786{
1787 EE_SELECTION sel =
1789
1790 if( sel.Size() != 1 )
1791 return 0;
1792
1793 bool clearSelection = sel.IsHover();
1794 EDA_ITEM* item = sel.Front();
1795
1796 if( item->Type() == SCH_FIELD_T )
1797 {
1798 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1799
1800 if( ( aEvent.IsAction( &EE_ACTIONS::editReference ) && field->GetId() != REFERENCE_FIELD )
1801 || ( aEvent.IsAction( &EE_ACTIONS::editValue ) && field->GetId() != VALUE_FIELD )
1802 || ( aEvent.IsAction( &EE_ACTIONS::editFootprint ) && field->GetId() != FOOTPRINT_FIELD ) )
1803 {
1804 item = field->GetParentSymbol();
1807 }
1808 }
1809
1810 if( item->Type() == SCH_SYMBOL_T )
1811 {
1812 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1813
1814 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1815 {
1817 }
1818 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1819 {
1820 editFieldText( symbol->GetField( VALUE_FIELD ) );
1821 }
1822 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1823 {
1824 if( !symbol->IsPower() )
1826 }
1827 }
1828 else if( item->Type() == SCH_FIELD_T )
1829 {
1830 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1831
1832 editFieldText( field );
1833
1834 if( !field->IsVisible() )
1835 clearSelection = true;
1836 }
1837 else if( item->Type() == SCH_PIN_T )
1838 {
1839 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
1840
1841 if( symbol )
1842 {
1843 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1844 {
1846 }
1847 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1848 {
1849 editFieldText( symbol->GetField( VALUE_FIELD ) );
1850 }
1851 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1852 {
1853 if( !symbol->IsPower() )
1855 }
1856 }
1857 }
1858
1859 if( clearSelection )
1861
1862 return 0;
1863}
1864
1865
1867{
1869 SCH_COMMIT commit( m_toolMgr );
1870 SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1871 bool moving = head && head->IsMoving();
1872
1873 if( selection.Empty() )
1874 return 0;
1875
1876 std::vector<SCH_ITEM*> autoplaceItems;
1877
1878 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1879 {
1880 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1881
1882 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
1883 autoplaceItems.push_back( item );
1884 else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
1885 autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
1886 }
1887
1888 for( SCH_ITEM* sch_item : autoplaceItems )
1889 {
1890 if( !moving && !sch_item->IsNew() )
1891 commit.Modify( sch_item, m_frame->GetScreen() );
1892
1893 sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1894
1895 updateItem( sch_item, true );
1896 }
1897
1898 if( moving )
1899 {
1901 }
1902 else
1903 {
1904 if( !commit.Empty() )
1905 commit.Push( _( "Autoplace Fields" ) );
1906
1907 if( selection.IsHover() )
1909 }
1910
1911 return 0;
1912}
1913
1914
1916{
1917 SCH_SYMBOL* selectedSymbol = nullptr;
1919
1920 if( !selection.Empty() )
1921 selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1922
1924
1925 if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1926 || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1927 {
1929 }
1930
1931 DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1932
1933 // QuasiModal required to invoke symbol browser
1934 dlg.ShowQuasiModal();
1935
1936 return 0;
1937}
1938
1939
1941{
1943
1944 if( selection.Empty() )
1945 return 0;
1946
1947 SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1948
1950 && symbol->GetBodyStyle() == BODY_STYLE::BASE )
1951 {
1952 return 0;
1953 }
1954
1956 && symbol->GetBodyStyle() == BODY_STYLE::DEMORGAN )
1957 {
1958 return 0;
1959 }
1960
1961 SCH_COMMIT commit( m_toolMgr );
1962
1963 if( !symbol->IsNew() )
1964 commit.Modify( symbol, m_frame->GetScreen() );
1965
1966 m_frame->FlipBodyStyle( symbol );
1967
1968 if( symbol->IsNew() )
1970
1971 if( !commit.Empty() )
1972 commit.Push( _( "Change Body Style" ) );
1973
1974 if( selection.IsHover() )
1976
1977 return 0;
1978}
1979
1980
1982{
1984 bool clearSelection = selection.IsHover();
1985
1986 if( selection.Empty() )
1987 {
1988 if( getView()->IsLayerVisible( LAYER_SCHEMATIC_DRAWINGSHEET ) )
1989 {
1991 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1992
1993 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1995 }
1996
1997 return 0;
1998 }
1999
2000 EDA_ITEM* curr_item = selection.Front();
2001
2002 // If a single pin is selected, promote to its parent symbol
2003 if( ( selection.GetSize() == 1 ) && ( curr_item->Type() == SCH_PIN_T ) )
2004 {
2005 EDA_ITEM* parent = curr_item->GetParent();
2006
2007 if( parent->Type() == SCH_SYMBOL_T )
2008 curr_item = parent;
2009 }
2010
2011 switch( curr_item->Type() )
2012 {
2013 case SCH_LINE_T:
2015 case SCH_JUNCTION_T:
2016 case SCH_TABLECELL_T:
2017 break;
2018
2019 default:
2020 if( selection.Size() > 1 )
2021 return 0;
2022
2023 break;
2024 }
2025
2026 switch( curr_item->Type() )
2027 {
2028 case SCH_SYMBOL_T:
2029 {
2030 int retval;
2031 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( curr_item );
2032
2033 // This needs to be scoped so the dialog destructor removes blocking status
2034 // before we launch the next dialog.
2035 {
2036 DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
2037
2038 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
2039 // frame. Therefore this dialog as a modal frame parent, MUST be run under
2040 // quasimodal mode for the quasimodal frame support to work. So don't use
2041 // the QUASIMODAL macros here.
2042 retval = symbolPropsDialog.ShowQuasiModal();
2043 }
2044
2045 if( retval == SYMBOL_PROPS_EDIT_OK )
2046 {
2049
2050 m_frame->OnModify();
2051 }
2052 else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
2053 {
2054 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true ) )
2055 {
2056 SYMBOL_EDIT_FRAME* editor = static_cast<SYMBOL_EDIT_FRAME*>( frame );
2057
2058 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
2059 blocking_win->Close( true );
2060
2061 // The broken library symbol link indicator cannot be edited.
2062 if( symbol->IsMissingLibSymbol() )
2063 return 0;
2064
2065 editor->LoadSymbolFromSchematic( symbol );
2066 editor->Show( true );
2067 editor->Raise();
2068 }
2069 }
2070 else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
2071 {
2072 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true ) )
2073 {
2074 SYMBOL_EDIT_FRAME* editor = static_cast<SYMBOL_EDIT_FRAME*>( frame );
2075
2076 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
2077 blocking_win->Close( true );
2078
2079 editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetBodyStyle() );
2080 editor->Show( true );
2081 editor->Raise();
2082 }
2083 }
2084 else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
2085 {
2087 dlg.ShowQuasiModal();
2088 }
2089 else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
2090 {
2092 dlg.ShowQuasiModal();
2093 }
2094
2095 break;
2096 }
2097
2098 case SCH_SHEET_T:
2099 {
2100 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( curr_item );
2101 bool isUndoable = false;
2102 bool doClearAnnotation = false;
2103 bool okPressed = false;
2104 bool updateHierarchyNavigator = false;
2105
2106 // Keep track of existing sheet paths. EditSheet() can modify this list.
2107 // Note that we use the validity checking/repairing version here just to make sure
2108 // we've got a valid hierarchy to begin with.
2109 SCH_SHEET_LIST originalHierarchy;
2110 originalHierarchy.BuildSheetList( &m_frame->Schematic().Root(), true );
2111
2112 SCH_COMMIT commit( m_toolMgr );
2113 commit.Modify( sheet, m_frame->GetScreen() );
2114 okPressed = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(), &isUndoable,
2115 &doClearAnnotation, &updateHierarchyNavigator );
2116
2117 if( okPressed )
2118 {
2119 if( isUndoable )
2120 {
2121 commit.Push( _( "Edit Sheet Properties" ) );
2122 }
2123 else
2124 {
2127 }
2128 }
2129 else
2130 {
2131 // If we are renaming files, the undo/redo list becomes invalid and must be cleared.
2133 m_frame->OnModify();
2134 }
2135
2136 // If the sheet file is changed and new sheet contents are loaded then we have to
2137 // clear the annotations on the new content (as it may have been set from some other
2138 // sheet path reference)
2139 if( doClearAnnotation )
2140 {
2141 SCH_SCREENS screensList( &m_frame->Schematic().Root() );
2142
2143 // We clear annotation of new sheet paths here:
2144 screensList.ClearAnnotationOfNewSheetPaths( originalHierarchy );
2145
2146 // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
2147 // path, but symbols managed by its sheet path must have their annotation cleared
2148 // because they are new:
2149 sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet(), false );
2150 }
2151
2152 if( okPressed )
2154
2155 if( updateHierarchyNavigator )
2157
2158 break;
2159 }
2160
2161 case SCH_SHEET_PIN_T:
2162 {
2163 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( curr_item );
2165
2166 // QuasiModal required for help dialog
2167 dlg.ShowQuasiModal();
2168 break;
2169 }
2170
2171 case SCH_TEXT_T:
2172 case SCH_TEXTBOX_T:
2173 {
2174 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
2175
2176 // QuasiModal required for syntax help and Scintilla auto-complete
2177 dlg.ShowQuasiModal();
2178 break;
2179 }
2180
2181 case SCH_TABLECELL_T:
2182 if( SELECTION_CONDITIONS::OnlyTypes( { SCH_TABLECELL_T } )( selection ) )
2183 {
2184 std::vector<SCH_TABLECELL*> cells;
2185
2186 for( EDA_ITEM* item : selection.Items() )
2187 cells.push_back( static_cast<SCH_TABLECELL*>( item ) );
2188
2190
2191 dlg.ShowModal();
2192
2194 {
2195 SCH_TABLE* table = static_cast<SCH_TABLE*>( cells[0]->GetParent() );
2196 DIALOG_TABLE_PROPERTIES tableDlg( m_frame, table );
2197
2198 tableDlg.ShowModal();
2199 }
2200 }
2201
2202 break;
2203
2204 case SCH_TABLE_T:
2205 {
2206 DIALOG_TABLE_PROPERTIES dlg( m_frame, static_cast<SCH_TABLE*>( curr_item ) );
2207
2208 // QuasiModal required for Scintilla auto-complete
2209 dlg.ShowQuasiModal();
2210 break;
2211 }
2212
2213 case SCH_LABEL_T:
2214 case SCH_GLOBAL_LABEL_T:
2215 case SCH_HIER_LABEL_T:
2217 {
2218 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( curr_item ) );
2219
2220 // QuasiModal for syntax help and Scintilla auto-complete
2221 dlg.ShowQuasiModal();
2222 break;
2223 }
2224
2225 case SCH_FIELD_T:
2226 {
2227 SCH_FIELD* field = static_cast<SCH_FIELD*>( curr_item );
2228
2229 editFieldText( field );
2230
2231 if( !field->IsVisible() )
2232 clearSelection = true;
2233
2234 break;
2235 }
2236
2237 case SCH_SHAPE_T:
2238 {
2239 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
2240
2241 dlg.ShowModal();
2242 break;
2243 }
2244
2245 case SCH_BITMAP_T:
2246 {
2247 SCH_BITMAP& bitmap = static_cast<SCH_BITMAP&>( *curr_item );
2248 DIALOG_IMAGE_PROPERTIES dlg( m_frame, bitmap );
2249
2250 if( dlg.ShowModal() == wxID_OK )
2251 {
2252 // The bitmap is cached in Opengl: clear the cache in case it has become invalid
2254 }
2255
2256 break;
2257 }
2258
2259 case SCH_RULE_AREA_T:
2260 {
2261 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
2262 dlg.SetTitle( _( "Rule Area Properties" ) );
2263
2264 dlg.ShowModal();
2265 break;
2266 }
2267
2268 case SCH_LINE_T:
2270 case SCH_JUNCTION_T:
2272 {
2273 std::deque<SCH_LINE*> lines;
2274
2275 for( EDA_ITEM* selItem : selection.Items() )
2276 lines.push_back( static_cast<SCH_LINE*>( selItem ) );
2277
2278 DIALOG_LINE_PROPERTIES dlg( m_frame, lines );
2279
2280 dlg.ShowModal();
2281 }
2282 else if( SELECTION_CONDITIONS::OnlyTypes( { SCH_JUNCTION_T } )( selection ) )
2283 {
2284 std::deque<SCH_JUNCTION*> junctions;
2285
2286 for( EDA_ITEM* selItem : selection.Items() )
2287 junctions.push_back( static_cast<SCH_JUNCTION*>( selItem ) );
2288
2289 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
2290
2291 dlg.ShowModal();
2292 }
2296 SCH_JUNCTION_T } )( selection ) )
2297 {
2298 std::deque<SCH_ITEM*> items;
2299
2300 for( EDA_ITEM* selItem : selection.Items() )
2301 items.push_back( static_cast<SCH_ITEM*>( selItem ) );
2302
2303 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, items );
2304
2305 dlg.ShowModal();
2306 }
2307 else
2308 {
2309 return 0;
2310 }
2311
2312 break;
2313
2314 case SCH_MARKER_T:
2315 if( SELECTION_CONDITIONS::OnlyTypes( { SCH_MARKER_T } )( selection ) )
2316 {
2318
2319 if( inspectionTool )
2320 inspectionTool->CrossProbe( static_cast<SCH_MARKER*> ( selection.Front() ) );
2321 }
2322 break;
2323
2324 case SCH_NO_CONNECT_T:
2325 case SCH_PIN_T:
2326 break;
2327
2328 default: // Unexpected item
2329 wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + curr_item->GetClass() );
2330 }
2331
2332 updateItem( curr_item, true );
2333
2334 if( clearSelection )
2336
2337 return 0;
2338}
2339
2340
2342{
2343 KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
2345 SCH_TEXT_T,
2346 SCH_TEXTBOX_T } );
2347 SCH_COMMIT commit( m_toolMgr );
2348
2349 for( unsigned int i = 0; i < selection.GetSize(); ++i )
2350 {
2351 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( selection.GetItem( i ) );
2352
2353 if( item && item->Type() != convertTo )
2354 {
2355 EDA_TEXT* sourceText = dynamic_cast<EDA_TEXT*>( item );
2356 bool selected = item->IsSelected();
2357 SCH_ITEM* newtext = nullptr;
2358 VECTOR2I position = item->GetPosition();
2359 wxString txt;
2360 wxString href;
2362 LABEL_FLAG_SHAPE shape = LABEL_FLAG_SHAPE::L_UNSPECIFIED;
2363
2364 switch( item->Type() )
2365 {
2366 case SCH_LABEL_T:
2367 case SCH_GLOBAL_LABEL_T:
2368 case SCH_HIER_LABEL_T:
2369 {
2370 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
2371
2372 txt = UnescapeString( label->GetText() );
2373 spinStyle = label->GetSpinStyle();
2374 shape = label->GetShape();
2375 href = label->GetHyperlink();
2376 break;
2377 }
2378
2380 {
2381 SCH_DIRECTIVE_LABEL* dirlabel = static_cast<SCH_DIRECTIVE_LABEL*>( item );
2382
2383 // a SCH_DIRECTIVE_LABEL has no text
2384 txt = _( "<empty>" );
2385
2386 spinStyle = dirlabel->GetSpinStyle();
2387 href = dirlabel->GetHyperlink();
2388 break;
2389 }
2390
2391 case SCH_TEXT_T:
2392 {
2393 SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
2394
2395 txt = text->GetText();
2396 href = text->GetHyperlink();
2397 break;
2398 }
2399
2400 case SCH_TEXTBOX_T:
2401 {
2402 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
2403 BOX2I bbox = textbox->GetBoundingBox();
2404
2405 bbox.SetOrigin( bbox.GetLeft() + textbox->GetMarginLeft(),
2406 bbox.GetTop() + textbox->GetMarginTop() );
2407 bbox.SetEnd( bbox.GetRight() - textbox->GetMarginRight(),
2408 bbox.GetBottom() - textbox->GetMarginBottom() );
2409
2410 if( convertTo == SCH_LABEL_T
2411 || convertTo == SCH_HIER_LABEL_T
2412 || convertTo == SCH_GLOBAL_LABEL_T )
2413 {
2414 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
2415 wxCHECK( text, 0 );
2416 int textSize = text->GetTextSize().y;
2417 bbox.Inflate( KiROUND( item->Schematic()->Settings().m_LabelSizeRatio * textSize ) );
2418 }
2419
2420 txt = textbox->GetText();
2421
2422 if( textbox->GetTextAngle().IsVertical() )
2423 {
2424 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2425 {
2426 spinStyle = SPIN_STYLE::SPIN::BOTTOM;
2427 position = VECTOR2I( bbox.Centre().x, bbox.GetOrigin().y );
2428 }
2429 else
2430 {
2431 spinStyle = SPIN_STYLE::SPIN::UP;
2432 position = VECTOR2I( bbox.Centre().x, bbox.GetEnd().y );
2433 }
2434 }
2435 else
2436 {
2437 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2438 {
2439 spinStyle = SPIN_STYLE::SPIN::LEFT;
2440 position = VECTOR2I( bbox.GetEnd().x, bbox.Centre().y );
2441 }
2442 else
2443 {
2444 spinStyle = SPIN_STYLE::SPIN::RIGHT;
2445 position = VECTOR2I( bbox.GetOrigin().x, bbox.Centre().y );
2446 }
2447 }
2448
2449 position = m_frame->GetNearestGridPosition( position );
2450 href = textbox->GetHyperlink();
2451 break;
2452 }
2453
2454 default:
2455 UNIMPLEMENTED_FOR( item->GetClass() );
2456 break;
2457 }
2458
2459 auto getValidNetname =
2460 []( const wxString& aText )
2461 {
2462 wxString local_txt = aText;
2463 local_txt.Replace( "\n", "_" );
2464 local_txt.Replace( "\r", "_" );
2465 local_txt.Replace( "\t", "_" );
2466
2467 // Bus groups can have spaces; bus vectors and signal names cannot
2468 if( !NET_SETTINGS::ParseBusGroup( aText, nullptr, nullptr ) )
2469 local_txt.Replace( " ", "_" );
2470
2471 // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
2472 local_txt = EscapeString( local_txt, CTX_NETNAME );
2473
2474 if( local_txt.IsEmpty() )
2475 return _( "<empty>" );
2476 else
2477 return local_txt;
2478 };
2479
2480 switch( convertTo )
2481 {
2482 case SCH_LABEL_T:
2483 {
2484 SCH_LABEL_BASE* new_label = new SCH_LABEL( position, getValidNetname( txt ) );
2485
2486 new_label->SetShape( shape );
2487 new_label->SetAttributes( *sourceText, false );
2488 new_label->SetSpinStyle( spinStyle );
2489 new_label->SetHyperlink( href );
2490
2491 if( item->Type() == SCH_GLOBAL_LABEL_T || item->Type() == SCH_HIER_LABEL_T )
2492 {
2493 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2494 new_label->MirrorVertically( position.y );
2495 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2496 new_label->MirrorVertically( position.y );
2497 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2498 new_label->MirrorHorizontally( position.x );
2499 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2500 new_label->MirrorHorizontally( position.x );
2501 }
2502
2503 newtext = new_label;
2504 break;
2505 }
2506
2507 case SCH_GLOBAL_LABEL_T:
2508 {
2509 SCH_LABEL_BASE* new_label = new SCH_GLOBALLABEL( position, getValidNetname( txt ) );
2510
2511 new_label->SetShape( shape );
2512 new_label->SetAttributes( *sourceText, false );
2513 new_label->SetSpinStyle( spinStyle );
2514 new_label->SetHyperlink( href );
2515
2516 if( item->Type() == SCH_LABEL_T )
2517 {
2518 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2519 new_label->MirrorVertically( position.y );
2520 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2521 new_label->MirrorVertically( position.y );
2522 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2523 new_label->MirrorHorizontally( position.x );
2524 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2525 new_label->MirrorHorizontally( position.x );
2526 }
2527
2528 newtext = new_label;
2529 break;
2530 }
2531
2532 case SCH_HIER_LABEL_T:
2533 {
2534 SCH_LABEL_BASE* new_label = new SCH_HIERLABEL( position, getValidNetname( txt ) );
2535
2536 new_label->SetShape( shape );
2537 new_label->SetAttributes( *sourceText, false );
2538 new_label->SetSpinStyle( spinStyle );
2539 new_label->SetHyperlink( href );
2540
2541 if( item->Type() == SCH_LABEL_T )
2542 {
2543 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2544 new_label->MirrorVertically( position.y );
2545 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2546 new_label->MirrorVertically( position.y );
2547 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2548 new_label->MirrorHorizontally( position.x );
2549 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2550 new_label->MirrorHorizontally( position.x );
2551 }
2552
2553 newtext = new_label;
2554 break;
2555 }
2556
2558 {
2559 SCH_LABEL_BASE* new_label = new SCH_DIRECTIVE_LABEL( position );
2560
2561 // A SCH_DIRECTIVE_LABEL usually has at least one field containing the net class
2562 // name. If we're copying from a text object assume the text is the netclass
2563 // name. Otherwise, we'll just copy the fields which will either have a netclass
2564 // or not.
2565 if( !dynamic_cast<SCH_LABEL_BASE*>( item ) )
2566 {
2567 SCH_FIELD netclass( position, 0, new_label, wxT( "Netclass" ) );
2568 netclass.SetText( txt );
2569 netclass.SetVisible( true );
2570 new_label->GetFields().push_back( netclass );
2571 }
2572
2573 new_label->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
2574 new_label->SetAttributes( *sourceText, false );
2575 new_label->SetSpinStyle( spinStyle );
2576 new_label->SetHyperlink( href );
2577 newtext = new_label;
2578 break;
2579 }
2580
2581 case SCH_TEXT_T:
2582 {
2583 SCH_TEXT* new_text = new SCH_TEXT( position, txt );
2584
2585 new_text->SetAttributes( *sourceText, false );
2586 new_text->SetHyperlink( href );
2587 newtext = new_text;
2588 break;
2589 }
2590
2591 case SCH_TEXTBOX_T:
2592 {
2593 SCH_TEXTBOX* new_textbox = new SCH_TEXTBOX( LAYER_NOTES, 0, FILL_T::NO_FILL, txt );
2594 BOX2I bbox = item->GetBoundingBox();
2595
2596 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
2597 bbox.Inflate( -label->GetLabelBoxExpansion() );
2598
2599 new_textbox->SetAttributes( *sourceText, false );
2600
2601 bbox.SetOrigin( bbox.GetLeft() - new_textbox->GetMarginLeft(),
2602 bbox.GetTop() - new_textbox->GetMarginTop() );
2603 bbox.SetEnd( bbox.GetRight() + new_textbox->GetMarginRight(),
2604 bbox.GetBottom() + new_textbox->GetMarginBottom() );
2605
2606 VECTOR2I topLeft = bbox.GetPosition();
2607 VECTOR2I botRight = bbox.GetEnd();
2608
2609 // Add 1/20 of the margin at the end to reduce line-breaking changes.
2610 int slop = new_textbox->GetLegacyTextMargin() / 20;
2611
2612 if( sourceText->GetTextAngle() == ANGLE_VERTICAL )
2613 {
2614 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2615 botRight.y += slop;
2616 else
2617 topLeft.y -= slop;
2618 }
2619 else
2620 {
2621 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2622 topLeft.x -= slop;
2623 else
2624 botRight.x += slop;
2625 }
2626
2627 new_textbox->SetPosition( topLeft );
2628 new_textbox->SetEnd( botRight );
2629
2630 new_textbox->SetHyperlink( href );
2631 newtext = new_textbox;
2632 break;
2633 }
2634
2635 default:
2636 UNIMPLEMENTED_FOR( wxString::Format( "%d.", convertTo ) );
2637 break;
2638 }
2639
2640 wxCHECK2( newtext, continue );
2641
2642 // Copy the old text item settings to the new one. Justifications are not copied
2643 // because they are not used in labels. Justifications will be set to default value
2644 // in the new text item type.
2645 //
2646 newtext->SetFlags( item->GetEditFlags() );
2647
2648 EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( item );
2649 EDA_TEXT* new_eda_text = dynamic_cast<EDA_TEXT*>( newtext );
2650
2651 wxCHECK2( eda_text && new_eda_text, continue );
2652
2653 new_eda_text->SetFont( eda_text->GetFont() );
2654 new_eda_text->SetTextSize( eda_text->GetTextSize() );
2655 new_eda_text->SetTextThickness( eda_text->GetTextThickness() );
2656
2657 // Must be after SetTextSize()
2658 new_eda_text->SetBold( eda_text->IsBold() );
2659 new_eda_text->SetItalic( eda_text->IsItalic() );
2660
2661 newtext->AutoplaceFields( m_frame->GetScreen(), false );
2662
2663 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item );
2664 SCH_LABEL_BASE* new_label = dynamic_cast<SCH_LABEL_BASE*>( newtext );
2665
2666 if( label && new_label )
2667 {
2668 new_label->AddFields( label->GetFields() );
2669
2670 // A SCH_GLOBALLABEL has a specific field, that has no meaning for
2671 // other labels, and expected to be the first field in list.
2672 // It is the first field in list for this kind of label
2673 // So remove field named "Intersheetrefs" if exists for other labels
2674 int min_idx = new_label->Type() == SCH_GLOBAL_LABEL_T ? 1 : 0;
2675 std::vector<SCH_FIELD>& fields = new_label->GetFields();
2676
2677 for( int ii = fields.size()-1; ii >= min_idx; ii-- )
2678 {
2679 if( fields[ii].GetCanonicalName() == wxT( "Intersheetrefs" ) )
2680 fields.erase( fields.begin() + ii );
2681 }
2682 }
2683
2684 if( selected )
2686
2687 if( !item->IsNew() )
2688 {
2690 commit.Removed( item, m_frame->GetScreen() );
2691
2692 m_frame->AddToScreen( newtext, m_frame->GetScreen() );
2693 commit.Added( newtext, m_frame->GetScreen() );
2694 }
2695
2696 if( selected )
2698
2699 // Otherwise, pointer is owned by the undo stack
2700 if( item->IsNew() )
2701 delete item;
2702 }
2703 }
2704
2705 if( !commit.Empty() )
2706 commit.Push( _( "Change To" ) );
2707
2708 if( selection.IsHover() )
2710
2711 return 0;
2712}
2713
2714
2716{
2717 static std::vector<KICAD_T> justifiableItems = {
2719 SCH_TEXT_T,
2722 };
2723
2724 EE_SELECTION& selection = m_selectionTool->RequestSelection( justifiableItems );
2725
2726 if( selection.GetSize() == 0 )
2727 return 0;
2728
2729 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
2730 bool moving = item->IsMoving();
2731 SCH_COMMIT localCommit( m_toolMgr );
2732 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
2733
2734 if( !commit )
2735 commit = &localCommit;
2736
2737 auto setJustify =
2738 [&]( EDA_TEXT* aTextItem )
2739 {
2740 if( aEvent.Matches( ACTIONS::leftJustify.MakeEvent() ) )
2741 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
2742 else if( aEvent.Matches( ACTIONS::centerJustify.MakeEvent() ) )
2743 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
2744 else
2745 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2746 };
2747
2748 for( EDA_ITEM* edaItem : selection )
2749 {
2750 item = static_cast<SCH_ITEM*>( edaItem );
2751
2752 if( !moving )
2753 commit->Modify( item, m_frame->GetScreen() );
2754
2755 if( item->Type() == SCH_FIELD_T )
2756 {
2757 setJustify( static_cast<SCH_FIELD*>( item ) );
2758
2759 // Now that we're re-justifying a field, they're no longer autoplaced.
2760 static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
2761 }
2762 else if( item->Type() == SCH_TEXT_T )
2763 {
2764 setJustify( static_cast<SCH_TEXT*>( item ) );
2765 }
2766 else if( item->Type() == SCH_TEXTBOX_T )
2767 {
2768 setJustify( static_cast<SCH_TEXTBOX*>( item ) );
2769 }
2770 else if( item->Type() == SCH_LABEL_T )
2771 {
2772 SCH_LABEL* label = static_cast<SCH_LABEL*>( item );
2773
2774 if( label->GetTextAngle() == ANGLE_HORIZONTAL )
2775 setJustify( label );
2776 }
2777
2778 m_frame->UpdateItem( item, false, true );
2779 }
2780
2781 // Update R-Tree for modified items
2782 for( EDA_ITEM* selected : selection )
2783 updateItem( selected, true );
2784
2785 if( item->IsMoving() )
2786 {
2788 }
2789 else
2790 {
2791 EE_SELECTION selectionCopy = selection;
2792
2793 if( selection.IsHover() )
2795
2796 if( !localCommit.Empty() )
2797 {
2798 if( aEvent.Matches( ACTIONS::leftJustify.MakeEvent() ) )
2799 localCommit.Push( _( "Left Justify" ) );
2800 else if( aEvent.Matches( ACTIONS::centerJustify.MakeEvent() ) )
2801 localCommit.Push( _( "Center Justify" ) );
2802 else
2803 localCommit.Push( _( "Right Justify" ) );
2804 }
2805 }
2806
2807 return 0;
2808}
2809
2810
2812{
2813 bool isSlice = aEvent.Matches( EE_ACTIONS::slice.MakeEvent() );
2816 SCH_SCREEN* screen = m_frame->GetScreen();
2817 SCH_COMMIT commit( m_toolMgr );
2818 std::vector<SCH_LINE*> lines;
2819
2820 for( EDA_ITEM* item : selection )
2821 {
2822 if( item->Type() == SCH_LINE_T )
2823 {
2824 SCH_LINE* line = static_cast<SCH_LINE*>( item );
2825
2826 if( !line->IsEndPoint( cursorPos ) )
2827 lines.push_back( line );
2828 }
2829 }
2830
2832
2833 for( SCH_LINE* line : lines )
2834 {
2835 SCH_LINE* newLine;
2836
2837 // We let the user select the break point if they're on a single line
2838 if( lines.size() == 1 && line->HitTest( cursorPos ) )
2839 m_frame->BreakSegment( &commit, line, cursorPos, &newLine, screen );
2840 else
2841 m_frame->BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
2842
2843 // Make sure both endpoints are deselected
2844 newLine->ClearFlags();
2845
2847 line->SetFlags( ENDPOINT );
2848
2849 // If we're a break, we want to drag both wires.
2850 // Side note: the drag/move tool only checks whether the first item is
2851 // new to determine if it should append undo or not, someday this should
2852 // be cleaned up and explictly controlled but for now the newLine
2853 // selection addition must be after the existing line.
2854 if( !isSlice )
2855 {
2856 m_selectionTool->AddItemToSel( newLine );
2857 newLine->SetFlags( STARTPOINT );
2858 }
2859 }
2860
2861 if( !lines.empty() )
2862 {
2864
2865 if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::drag, &commit, isSlice ) )
2866 commit.Push( isSlice ? _( "Slice Wire" ) : _( "Break Wire" ) );
2867 else
2868 commit.Revert();
2869 }
2870
2871 return 0;
2872}
2873
2874
2876{
2878 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2879 SCH_COMMIT commit( m_toolMgr );
2880
2881 if( !sheet || !sheet->HasUndefinedPins() )
2882 return 0;
2883
2884 if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
2885 return 0;
2886
2887 commit.Modify( sheet, m_frame->GetScreen() );
2888
2889 sheet->CleanupSheet();
2890
2891 updateItem( sheet, true );
2892
2893 commit.Push( _( "Cleanup Sheet Pins" ) );
2894
2895 if( selection.IsHover() )
2897
2898 return 0;
2899}
2900
2901
2903{
2905
2906 if( selection.GetSize() > 1 )
2907 return 0;
2908
2909 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2910
2912
2913 SCH_SCREEN* screen;
2914
2915 if( sheet )
2916 {
2917 // When changing the page number of a selected sheet, the current screen owns the sheet.
2918 screen = m_frame->GetScreen();
2919
2920 instance.push_back( sheet );
2921 }
2922 else
2923 {
2924 SCH_SHEET_PATH prevInstance = instance;
2925
2926 // When change the page number in the screen, the previous screen owns the sheet.
2927 if( prevInstance.size() )
2928 {
2929 prevInstance.pop_back();
2930 screen = prevInstance.LastScreen();
2931 }
2932 else
2933 {
2934 // The root sheet and root screen are effectively the same thing.
2935 screen = m_frame->GetScreen();
2936 }
2937
2938 sheet = m_frame->GetCurrentSheet().Last();
2939 }
2940
2941 wxString msg;
2942 wxString sheetPath = instance.PathHumanReadable( false );
2943 wxString pageNumber = instance.GetPageNumber();
2944
2945 msg.Printf( _( "Enter page number for sheet path%s" ),
2946 ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
2947
2948 wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
2949
2950 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
2951
2952 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
2953 return 0;
2954
2955 m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
2956
2957 instance.SetPageNumber( dlg.GetValue() );
2958
2959 if( instance == m_frame->GetCurrentSheet() )
2960 {
2961 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
2963 }
2964
2965 m_frame->OnModify();
2966
2967 // Update the hierarchy navigator labels if needed
2968 if( pageNumber != dlg.GetValue() )
2970
2971 return 0;
2972}
2973
2974
2976{
2977 const ACTIONS::INCREMENT incParam = aEvent.Parameter<ACTIONS::INCREMENT>();
2978 static const std::vector<KICAD_T> incrementable = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T,
2980 EE_SELECTION& selection = m_selectionTool->RequestSelection( incrementable );
2981
2982 if( selection.Empty() )
2983 return 0;
2984
2985 KICAD_T type = selection.Front()->Type();
2986 bool allSameType = true;
2987 for( EDA_ITEM* item : selection )
2988 {
2989 if( item->Type() != type )
2990 {
2991 allSameType = false;
2992 break;
2993 }
2994 }
2995
2996 // Incrementing multiple types at once seems confusing
2997 // though it would work.
2998 if( !allSameType )
2999 return 0;
3000
3001 STRING_INCREMENTER incrementer;
3002 // In schematics, it's probably less common to be operating
3003 // on pin numbers which are uusally IOSQXZ-skippy.
3004 incrementer.SetSkipIOSQXZ( false );
3005
3006 SCH_COMMIT commit( m_frame );
3007
3008 for( EDA_ITEM* item : selection )
3009 {
3010 switch( item->Type() )
3011 {
3012 case SCH_LABEL_T:
3013 case SCH_GLOBAL_LABEL_T:
3014 case SCH_HIER_LABEL_T:
3015 case SCH_TEXT_T:
3016 {
3017 SCH_TEXT& label = static_cast<SCH_TEXT&>( *item );
3018
3019 std::optional<wxString> newLabel =
3020 incrementer.Increment( label.GetText(), incParam.Delta, incParam.Index );
3021 if( newLabel )
3022 {
3023 commit.Modify( &label, m_frame->GetScreen() );
3024 label.SetText( *newLabel );
3025 }
3026 break;
3027 }
3028 default:
3029 // No increment for other items (yet)
3030 break;
3031 }
3032 }
3033
3034 commit.Push( _( "Increment" ) );
3035
3036 return 0;
3037}
3038
3039
3041{
3042 return m_toolMgr->RunAction( EE_ACTIONS::importSheet, aEvent.Parameter<wxString*>() );
3043}
3044
3045
3047{
3049 SCH_COMMIT commit( m_toolMgr );
3050
3051 if( selection.Empty() )
3052 return 0;
3053
3054 for( EDA_ITEM* item : selection )
3055 {
3056 if( item->Type() == SCH_SYMBOL_T )
3057 {
3058 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
3059
3060 commit.Modify( symbol, m_frame->GetScreen() );
3061
3062 if( aEvent.IsAction( &EE_ACTIONS::setDNP ) )
3063 symbol->SetDNP( true );
3064
3066 symbol->SetExcludedFromSim( true );
3067
3069 symbol->SetExcludedFromBOM( true );
3070
3072 symbol->SetExcludedFromBoard( true );
3073 }
3074 }
3075
3076 if( !commit.Empty() )
3077 commit.Push( _( "Set Attribute" ) );
3078
3079 return 0;
3080}
3081
3082
3084{
3086 SCH_COMMIT commit( m_toolMgr );
3087
3088 if( selection.Empty() )
3089 return 0;
3090
3091 for( EDA_ITEM* item : selection )
3092 {
3093 if( item->Type() == SCH_SYMBOL_T )
3094 {
3095 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
3096
3097 commit.Modify( symbol, m_frame->GetScreen() );
3098
3099 if( aEvent.IsAction( &EE_ACTIONS::unsetDNP ) )
3100 symbol->SetDNP( false );
3101
3103 symbol->SetExcludedFromSim( false );
3104
3106 symbol->SetExcludedFromBOM( false );
3107
3109 symbol->SetExcludedFromBoard( false );
3110 }
3111 }
3112
3113 if( !commit.Empty() )
3114 commit.Push( _( "Clear Attribute" ) );
3115
3116 return 0;
3117}
3118
3119
3121{
3123 SCH_COMMIT commit( m_toolMgr );
3124
3125 if( selection.Empty() )
3126 return 0;
3127
3128 for( EDA_ITEM* item : selection )
3129 {
3130 if( item->Type() == SCH_SYMBOL_T )
3131 {
3132 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
3133
3134 commit.Modify( symbol, m_frame->GetScreen() );
3135
3136 if( aEvent.IsAction( &EE_ACTIONS::toggleDNP ) )
3137 symbol->SetDNP( !symbol->GetDNP() );
3138
3140 symbol->SetExcludedFromSim( !symbol->GetExcludedFromSim() );
3141
3143 symbol->SetExcludedFromBOM( !symbol->GetExcludedFromBOM() );
3144
3146 symbol->SetExcludedFromBoard( !symbol->GetExcludedFromBoard() );
3147 }
3148 }
3149
3150 if( !commit.Empty() )
3151 commit.Push( _( "Toggle Attribute" ) );
3152
3153 return 0;
3154
3155}
3156
3157
3159{
3160 // clang-format off
3166 Go( &SCH_EDIT_TOOL::Swap, EE_ACTIONS::swap.MakeEvent() );
3169
3175
3197
3200
3213
3217
3219 // clang-format on
3220}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
static TOOL_ACTION decrementPrimary
Definition: actions.h:89
static TOOL_ACTION paste
Definition: actions.h:73
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 pasteSpecial
Definition: actions.h:74
static TOOL_ACTION rightJustify
Definition: actions.h:82
static TOOL_ACTION pageSettings
Definition: actions.h:56
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 deleteTool
Definition: actions.h:79
static TOOL_ACTION increment
Definition: actions.h:87
static TOOL_ACTION leftJustify
Definition: actions.h:80
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
static TOOL_ACTION centerJustify
Definition: actions.h:81
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:49
TOOL_MANAGER * getToolManager() const
void Clear()
Remove all the entries from the menu (as well as its title).
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:92
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:78
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
void update() override
Update menu state stub.
void SetPageNumber(const wxString &aPageNumber)
Definition: base_screen.h:79
void update() override
Update menu state stub.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
constexpr const Vec & GetPosition() const
Definition: box2.h:211
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr const Vec GetEnd() const
Definition: box2.h:212
constexpr void SetOrigin(const Vec &pos)
Definition: box2.h:237
constexpr Vec Centre() const
Definition: box2.h:97
constexpr const Vec GetCenter() const
Definition: box2.h:230
constexpr coord_type GetLeft() const
Definition: box2.h:228
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr coord_type GetRight() const
Definition: box2.h:217
constexpr void SetEnd(coord_type x, coord_type y)
Definition: box2.h:297
constexpr coord_type GetTop() const
Definition: box2.h:229
constexpr coord_type GetBottom() const
Definition: box2.h:222
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
int m_Threshold
Definition: collector.h:234
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been removed.
Definition: commit.h:92
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition: commit.h:86
bool Empty() const
Returns status of an item.
Definition: commit.h:144
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:98
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.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
Dialog to update or change schematic library symbols.
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 used to edit SCH_SYMBOL objects in a schematic.
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
bool IsHorizontal() const
Definition: eda_angle.h:138
bool IsVertical() const
Definition: eda_angle.h:143
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
void ShowInfoBarWarning(const wxString &aWarningMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and a warning icon on the left ...
VECTOR2I GetNearestGridPosition(const VECTOR2I &aPosition) const
Return the nearest aGridSize location to aPosition.
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
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:77
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
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
bool IsSelected() const
Definition: eda_item.h:110
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:176
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:131
virtual wxString GetClass() const =0
Return the class name.
bool IsMoving() const
Definition: eda_item.h:108
bool IsNew() const
Definition: eda_item.h:107
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:171
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
bool IsItalic() const
Definition: eda_text.h:152
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:130
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:419
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
KIFONT::FONT * GetFont() const
Definition: eda_text.h:230
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:337
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:321
wxString GetHyperlink() const
Definition: eda_text.h:381
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:183
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:290
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:196
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition: eda_text.cpp:240
bool IsBold() const
Definition: eda_text.h:167
void SetHyperlink(wxString aLink)
Definition: eda_text.h:382
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:186
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:182
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:204
int GetTextThickness() const
Definition: eda_text.h:122
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition: eda_text.cpp:212
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:403
VECTOR2I GetTextSize() const
Definition: eda_text.h:241
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:313
PANEL_ANNOTATE m_AnnotatePanel
AUTOPLACE_FIELDS m_AutoplaceFields
static TOOL_ACTION mirrorV
Definition: ee_actions.h:132
static TOOL_ACTION unsetDNP
Definition: ee_actions.h:202
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 toggleExcludeFromSimulation
Definition: ee_actions.h:197
static TOOL_ACTION unsetExcludeFromSimulation
Definition: ee_actions.h:196
static TOOL_ACTION setExcludeFromBoard
Definition: ee_actions.h:198
static TOOL_ACTION move
Definition: ee_actions.h:127
static TOOL_ACTION clearHighlight
Definition: ee_actions.h:309
static TOOL_ACTION toGLabel
Definition: ee_actions.h:147
static TOOL_ACTION toggleExcludeFromBoard
Definition: ee_actions.h:200
static TOOL_ACTION setDNP
Definition: ee_actions.h:201
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:243
static TOOL_ACTION slice
Definition: ee_actions.h:151
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION drag
Definition: ee_actions.h:128
static TOOL_ACTION toText
Definition: ee_actions.h:148
static TOOL_ACTION placeClassLabel
Definition: ee_actions.h:90
static TOOL_ACTION placeNextSymbolUnit
Definition: ee_actions.h:80
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:142
static TOOL_ACTION toggleExcludeFromBOM
Definition: ee_actions.h:194
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:139
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:141
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:131
static TOOL_ACTION editValue
Definition: ee_actions.h:137
static TOOL_ACTION toLabel
Definition: ee_actions.h:144
static TOOL_ACTION toTextBox
Definition: ee_actions.h:149
static TOOL_ACTION breakWire
Definition: ee_actions.h:150
static TOOL_ACTION mirrorH
Definition: ee_actions.h:133
static TOOL_ACTION rotateCW
Definition: ee_actions.h:130
static TOOL_ACTION unsetExcludeFromBOM
Definition: ee_actions.h:193
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:179
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:91
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:60
static TOOL_ACTION ddAppendFile
Definition: ee_actions.h:315
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:92
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
static TOOL_ACTION editPageNumber
Definition: ee_actions.h:170
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:165
static TOOL_ACTION editFootprint
Definition: ee_actions.h:138
static TOOL_ACTION enterSheet
Definition: ee_actions.h:232
static TOOL_ACTION editReference
Definition: ee_actions.h:136
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:164
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:102
static TOOL_ACTION setExcludeFromBOM
Definition: ee_actions.h:192
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:163
static TOOL_ACTION setExcludeFromSimulation
Definition: ee_actions.h:195
static TOOL_ACTION unsetExcludeFromBoard
Definition: ee_actions.h:199
static TOOL_ACTION toCLabel
Definition: ee_actions.h:145
static TOOL_ACTION placeLabel
Definition: ee_actions.h:89
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:129
static TOOL_ACTION toHLabel
Definition: ee_actions.h:146
static TOOL_ACTION editTextAndGraphics
Definition: ee_actions.h:244
static TOOL_ACTION toggleDNP
Definition: ee_actions.h:203
static TOOL_ACTION importSheet
Definition: ee_actions.h:97
static TOOL_ACTION swap
Definition: ee_actions.h:134
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:140
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:166
void Collect(SCH_SCREEN *aScreen, const std::vector< KICAD_T > &aScanTypes, const VECTOR2I &aPos, int aUnit=0, int aConvert=0)
Scan a EDA_ITEM using this class's Inspector method which does the collection.
static const std::vector< KICAD_T > FieldOwners
Definition: ee_collectors.h:44
static SELECTION_CONDITION SingleSymbol
static SELECTION_CONDITION AllPinsOrSheetPins
static SELECTION_CONDITION SingleMultiFunctionPin
static SELECTION_CONDITION SingleSymbolOrPower
static SELECTION_CONDITION SingleMultiUnitSymbol
static SELECTION_CONDITION SingleDeMorganSymbol
static SELECTION_CONDITION MultipleSymbolsOrPower
int CrossProbe(const TOOL_EVENT &aEvent)
Called when clicking on a item:
bool empty() const
Definition: sch_rtree.h:176
void GuessSelectionCandidates(EE_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
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.
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
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:103
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1454
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:418
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
static bool ParseBusGroup(const wxString &aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parse a bus group label into the name and a list of components.
A singleton reporter that reports to nowhere.
Definition: reporter.h:203
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
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 SetSnapping(bool aSnap)
Definition: picker_tool.h:66
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
void update() override
Update menu state stub.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
These are loaded from Eeschema settings but then overwritten by the project settings.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:314
SCH_SHEET & Root() const
Definition: schematic.h:121
void RefreshHierarchy()
Definition: schematic.cpp:222
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:40
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
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.).
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
Schematic editor (Eeschema) main window.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SchematicCleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void UpdateHierarchyNavigator(bool aRefreshNetNavigator=true)
Update the hierarchy navigation tree and history.
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend, bool aDirtyConnectivity=true)
Create a copy of the current schematic item, and put it in the undo list.
void AnnotateSymbols(SCH_COMMIT *aCommit, ANNOTATE_SCOPE_T aAnnotateScope, ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption, bool aRecursive, int aStartNumber, bool aResetAnnotation, bool aRepairTimestamps, REPORTER &aReporter)
Annotate the symbols in the schematic that are not currently annotated.
Definition: annotate.cpp:212
SCH_SHEET_PATH & GetCurrentSheet() const
SCHEMATIC & Schematic() const
const std::vector< std::unique_ptr< SCH_ITEM > > & GetRepeatItems() const
Return the items which are to be repeated with the insert key.
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aIsUndoable=nullptr, bool *aClearAnnotationNewItems=nullptr, bool *aUpdateHierarchyNavigator=nullptr, wxString *aSourceSheetFilename=nullptr)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:599
void FlipBodyStyle(SCH_SYMBOL *aSymbol)
Definition: picksymbol.cpp:176
void OnPageSettingsChange() override
Called when modifying the page settings.
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet)
Verify that aSheet will not cause a recursion error in aCurrentSheet.
Definition: sheet.cpp:51
void UpdateLabelsHierarchyNavigator()
Update the hierarchy navigation tree labels.
void BreakSegment(SCH_COMMIT *aCommit, SCH_LINE *aSegment, const VECTOR2I &aPoint, SCH_LINE **aNewSegment, SCH_SCREEN *aScreen)
Break a single segment into two at the specified point.
const wxString & GetHighlightedConnection() const
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
void AddCopyForRepeatItem(const SCH_ITEM *aItem)
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void DeleteJunction(SCH_COMMIT *aCommit, SCH_ITEM *aItem)
Removes a given junction and heals any wire segments under the junction.
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
int ChangeBodyStyle(const TOOL_EVENT &aEvent)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
static const std::vector< KICAD_T > RotatableItems
Definition: sch_edit_tool.h:42
EDA_ITEM * m_pickerItem
int EditField(const TOOL_EVENT &aEvent)
int EditPageNumber(const TOOL_EVENT &aEvent)
int DoDelete(const TOOL_EVENT &aEvent)
Run the deletion tool.
int UnsetAttribute(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
int CleanupSheetPins(const TOOL_EVENT &aEvent)
void editFieldText(SCH_FIELD *aField)
Set up handlers for various events.
int Mirror(const TOOL_EVENT &aEvent)
int GlobalEdit(const TOOL_EVENT &aEvent)
Delete the selected items, or the item under the cursor.
int SetAttribute(const TOOL_EVENT &aEvent)
Modify Attributes.
int Properties(const TOOL_EVENT &aEvent)
int Rotate(const TOOL_EVENT &aEvent)
int Increment(const TOOL_EVENT &aEvent)
Increment/decrement something about an item.
int BreakWire(const TOOL_EVENT &aEvent)
int DdAppendFile(const TOOL_EVENT &aEvent)
Drag and drop.
int JustifyText(const TOOL_EVENT &aEvent)
int ToggleAttribute(const TOOL_EVENT &aEvent)
int AutoplaceFields(const TOOL_EVENT &aEvent)
int Swap(const TOOL_EVENT &aEvent)
int ChangeSymbols(const TOOL_EVENT &aEvent)
int ChangeTextType(const TOOL_EVENT &aEvent)
Change a text type to another one.
int InteractiveDelete(const TOOL_EVENT &aEvent)
int RepeatDrawItem(const TOOL_EVENT &aEvent)
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
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:1025
VECTOR2I GetPosition() const override
Definition: sch_field.cpp:1485
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: sch_field.cpp:1252
int GetId() const
Definition: sch_field.h:133
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1227
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1465
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1212
VECTOR2I GetParentPosition() const
Definition: sch_field.cpp:1501
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
virtual bool IsConnectable() const
Definition: sch_item.h:449
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:166
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
int GetBodyStyle() const
Definition: sch_item.h:232
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
Definition: sch_item.h:343
virtual void Move(const VECTOR2I &aMoveVector)
Move the item by aMoveVector to a new position.
Definition: sch_item.h:335
int GetUnit() const
Definition: sch_item.h:229
void ClearFieldsAutoplaced()
Definition: sch_item.h:551
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 AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:566
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:176
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:560
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:579
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:464
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:131
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:181
virtual void MirrorVertically(int aCenter)
Mirror item vertically about aCenter.
Definition: sch_item.h:351
void AddFields(const std::vector< SCH_FIELD > &aFields)
Definition: sch_label.h:214
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:448
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:332
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:178
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:177
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:467
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:201
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:297
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.)
int AddJunctionsIfNeeded(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Handle the addition of junctions to a selection of objects.
int TrimOverLappingWires(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Logic to remove wires when overlapping correct items.
static bool IsDrawingLineWireOrBus(const SELECTION &aSelection)
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_line.cpp:413
VECTOR2I GetEndPoint() const
Definition: sch_line.h:141
VECTOR2I GetStartPoint() const
Definition: sch_line.h:136
bool IsEndPoint(const VECTOR2I &aPoint) const
Definition: sch_line.h:90
const std::map< wxString, ALT > & GetAlternates() const
Definition: sch_pin.h:127
const wxString & GetName() const
Definition: sch_pin.cpp:375
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:712
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicates that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:487
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
const wxString & GetFileName() const
Definition: sch_screen.h:143
SCH_ITEM * GetItem(const VECTOR2I &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:392
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:118
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear the annotation for the symbols in aSheetPath on the screen.
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:71
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_shape.cpp:265
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
SHEET_SIDE GetSide() const
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
void SetSide(SHEET_SIDE aEdge)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:312
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:306
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:756
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:616
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:440
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:502
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:110
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:724
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:745
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:923
Schematic symbol object.
Definition: sch_symbol.h:104
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:856
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:939
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:237
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:193
int GetOrientation() const
Get the display symbol orientation.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:212
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
bool IsPower() const override
VECTOR2I GetPosition() const override
Definition: sch_table.cpp:115
VECTOR2I GetEnd() const
Definition: sch_table.cpp:121
int GetMarginBottom() const
Definition: sch_textbox.h:66
int GetLegacyTextMargin() const
Definition: sch_textbox.cpp:76
int GetMarginLeft() const
Definition: sch_textbox.h:63
int GetMarginRight() const
Definition: sch_textbox.h:65
int GetMarginTop() const
Definition: sch_textbox.h:64
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:209
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:221
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
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 bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
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 void Add(EDA_ITEM *aItem)
Definition: selection.cpp:42
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:75
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:121
VECTOR2I GetReferencePoint() const
Definition: selection.cpp:171
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
int Size() const
Returns the number of selected parts.
Definition: selection.h:116
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:177
std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:265
bool OnlyContains(std::vector< KICAD_T > aList) const
Checks if all items in the selection have a type in aList.
Definition: selection.cpp:213
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
bool HasReferencePoint() const
Definition: selection.h:211
size_t CountType(KICAD_T aType) const
Definition: selection.cpp:157
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
unsigned CCWRotationsTo(const SPIN_STYLE &aOther) const
Get CCW rotation needed to get to the given spin style.
Definition: sch_label.cpp:155
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
The symbol library editor main window.
void update() override
Update menu state stub.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
void SetDNP(bool aDNP)
Definition: symbol.h:154
bool GetExcludedFromBoard() const
Definition: symbol.h:148
bool GetExcludedFromBOM() const
Definition: symbol.h:142
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition: symbol.h:135
bool GetDNP() const
Set or clear the 'Do Not Populate' flaga.
Definition: symbol.h:153
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:141
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: symbol.h:147
bool GetExcludedFromSim() const override
Definition: symbol.h:136
bool IsCurrentTool(const TOOL_ACTION &aAction) const
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
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 DisableGridSnapping() const
Definition: tool_event.h:363
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
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 IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:250
This file is part of the common library.
@ SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL
@ SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL
@ SYMBOL_PROPS_WANT_UPDATE_SYMBOL
@ SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL
@ SYMBOL_PROPS_EDIT_OK
#define _(s)
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:398
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
#define IS_NEW
New item, just created.
#define SELECTED_BY_DRAG
Item was algorithmically selected as a dragged item.
#define STRUCT_DELETED
flag indication structures to be erased
#define ENDPOINT
ends. (Used to support dragging.)
#define STARTPOINT
When a line is selected, these flags indicate which.
#define HITTEST_THRESHOLD_PIXELS
static std::vector< KICAD_T > sheetTypes
std::set< int > GetUnplacedUnitsForSymbol(const SCH_SYMBOL &aSym)
Get a list of unplaced (i.e.
@ ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL
Definition: eeschema_id.h:95
@ ID_POPUP_SCH_PIN_TRICKS_WIRE
Definition: eeschema_id.h:93
@ ID_POPUP_SCH_ALT_PIN_FUNCTION
Definition: eeschema_id.h:99
@ ID_POPUP_SCH_SELECT_UNIT1
Definition: eeschema_id.h:83
@ ID_POPUP_SCH_SELECT_UNIT
Definition: eeschema_id.h:82
@ ID_POPUP_SCH_SELECT_BASE
Definition: eeschema_id.h:88
@ ID_POPUP_SCH_SELECT_ALT
Definition: eeschema_id.h:89
@ ID_POPUP_SCH_PIN_TRICKS_NET_LABEL
Definition: eeschema_id.h:94
@ ID_POPUP_SCH_PIN_TRICKS_NO_CONNECT
Definition: eeschema_id.h:92
@ ID_POPUP_SCH_SELECT_UNIT_END
Definition: eeschema_id.h:86
@ ID_POPUP_SCH_ALT_PIN_FUNCTION_END
Definition: eeschema_id.h:100
@ ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL
Definition: eeschema_id.h:96
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ LAYER_NOTES
Definition: layer_ids.h:371
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:398
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
static void swapFieldPositionsWithMatching(std::vector< SCH_FIELD > &aAFields, std::vector< SCH_FIELD > &aBFields, unsigned aFallbackRotationsCCW)
Swap the positions of the fields in the two lists, aAFields and aBFields, relative to their parent po...
static std::vector< KICAD_T > deletableItems
const std::vector< KICAD_T > swappableItems
LABEL_FLAG_SHAPE
Definition: sch_label.h:98
ANNOTATE_ORDER_T
Schematic annotation order options.
@ ANNOTATE_SELECTION
Annotate the selection.
ANNOTATE_ALGO_T
Schematic annotation type options.
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
Definition: sch_sheet_pin.h:46
@ SYM_MIRROR_Y
Definition: sch_symbol.h:85
@ SYM_MIRROR_X
Definition: sch_symbol.h:84
wxString UnescapeString(const wxString &aSource)
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_NETNAME
Definition: string_utils.h:53
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
#define DO_TRANSLATE
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
GR_TEXT_H_ALIGN_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
GR_TEXT_V_ALIGN_T
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
@ SCH_LINE_T
Definition: typeinfo.h:163
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:160
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_TABLECELL_T
Definition: typeinfo.h:166
@ SCH_ITEM_LOCATE_WIRE_T
Definition: typeinfo.h:185
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_ITEM_LOCATE_BUS_T
Definition: typeinfo.h:186
@ SCH_MARKER_T
Definition: typeinfo.h:158
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_RULE_AREA_T
Definition: typeinfo.h:170
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:162
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:190
@ SCH_ITEM_LOCATE_GRAPHIC_LINE_T
Definition: typeinfo.h:187
@ SCHEMATIC_T
Definition: typeinfo.h:203
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_TEXT_T
Definition: typeinfo.h:151
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:161
@ SCH_BITMAP_T
Definition: typeinfo.h:164
@ SCH_TEXTBOX_T
Definition: typeinfo.h:152
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
@ SCH_JUNCTION_T
Definition: typeinfo.h:159
@ SCH_PIN_T
Definition: typeinfo.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691