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>
31#include <tools/sch_move_tool.h>
33#include <ee_actions.h>
34#include <confirm.h>
35#include <string_utils.h>
36#include <sch_bitmap.h>
37#include <sch_bus_entry.h>
38#include <sch_commit.h>
39#include <sch_edit_frame.h>
40#include <sch_item.h>
41#include <sch_junction.h>
42#include <sch_line.h>
43#include <sch_marker.h>
44#include <sch_rule_area.h>
45#include <sch_symbol.h>
46#include <sch_shape.h>
47#include <sch_sheet.h>
48#include <sch_sheet_pin.h>
49#include <sch_text.h>
50#include <sch_textbox.h>
51#include <sch_table.h>
52#include <sch_tablecell.h>
53#include <sch_view.h>
54#include <schematic.h>
56#include <eeschema_id.h>
67#include <dialogs/dialog_text_properties.h>
68#include <dialogs/dialog_tablecell_properties.h>
69#include <dialogs/dialog_table_properties.h>
70#include <pgm_base.h>
73#include <core/kicad_algo.h>
74#include <wx/textdlg.h>
76
78{
79public:
81 ACTION_MENU( true )
82 {
83 SetIcon( BITMAPS::component_select_unit );
84 SetTitle( _( "Symbol Unit" ) );
85 }
86
87protected:
88 ACTION_MENU* create() const override
89 {
90 return new SYMBOL_UNIT_MENU();
91 }
92
93private:
94 void update() override
95 {
97 EE_SELECTION& selection = selTool->GetSelection();
98 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
99
100 Clear();
101
102 wxCHECK( symbol, /* void */ );
103
104 int unit = symbol->GetUnit();
105
106 for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
107 {
108 wxString num_unit;
109 num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
110
111 wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
112 wxITEM_CHECK );
113
114 if( unit == ii + 1 )
115 item->Check( true );
116
117 // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_END
118 // See eeschema_id to modify this value.
120 break; // We have used all IDs for these submenus
121 }
122 }
123};
124
125
127{
128public:
130 ACTION_MENU( true )
131 {
132 SetIcon( BITMAPS::component_select_unit );
133 SetTitle( _( "Pin Function" ) );
134 }
135
136protected:
137 ACTION_MENU* create() const override
138 {
139 return new ALT_PIN_FUNCTION_MENU();
140 }
141
142private:
143 void update() override
144 {
146 EE_SELECTION& selection = selTool->GetSelection();
147 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
148 SCH_PIN* libPin = pin ? pin->GetLibPin() : nullptr;
149
150 Clear();
151
152 wxCHECK( libPin, /* void */ );
153
154 wxMenuItem* item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION, libPin->GetName(), wxEmptyString,
155 wxITEM_CHECK );
156
157 if( pin->GetAlt().IsEmpty() )
158 item->Check( true );
159
160 int ii = 1;
161
162 for( const auto& [ name, definition ] : libPin->GetAlternates() )
163 {
164 item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION + ii, name, wxEmptyString, wxITEM_CHECK );
165
166 if( name == pin->GetAlt() )
167 item->Check( true );
168
169 // The ID max for these submenus is ID_POPUP_SCH_ALT_PIN_FUNCTION_END
170 // See eeschema_id to modify this value.
172 break; // We have used all IDs for these submenus
173 }
174 }
175};
176
177
179{
180public:
182 {
183 SetIcon( BITMAPS::pin );
184 SetTitle( _( "Pin Helpers" ) );
185 }
186
187protected:
188 ACTION_MENU* create() const override { return new PIN_TRICKS_MENU(); }
189
190private:
191 void update() override
192 {
194 EE_SELECTION& selection = selTool->GetSelection();
195 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
196
197 Clear();
198
199 if( !pin )
200 return;
201
202 Add( _( "Wire" ), ID_POPUP_SCH_PIN_TRICKS_WIRE, BITMAPS::add_line );
203 Add( _( "No Connect" ), ID_POPUP_SCH_PIN_TRICKS_NO_CONNECT, BITMAPS::noconn );
204 Add( _( "Net Label" ), ID_POPUP_SCH_PIN_TRICKS_NET_LABEL, BITMAPS::add_label );
205 Add( _( "Hierarchical Label" ), ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL, BITMAPS::add_hierarchical_label );
206 Add( _( "Global Label" ), ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL, BITMAPS::add_glabel );
207 }
208};
209
210
212 EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
213{
214 m_pickerItem = nullptr;
215}
216
217
219
221{
223
226
227 wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
228
229 auto hasElements =
230 [this]( const SELECTION& aSel )
231 {
232 return !m_frame->GetScreen()->Items().empty();
233 };
234
235 auto sheetHasUndefinedPins =
236 []( const SELECTION& aSel )
237 {
238 if( aSel.Size() == 1 && aSel.Front()->Type() == SCH_SHEET_T )
239 return static_cast<SCH_SHEET*>( aSel.Front() )->HasUndefinedPins();
240
241 return false;
242 };
243
244 auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
245
246 auto haveHighlight =
247 [&]( const SELECTION& sel )
248 {
249 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
250
251 return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
252 };
253
254 auto anyTextTool =
255 [this]( const SELECTION& aSel )
256 {
262 };
263
264 auto duplicateCondition =
265 []( const SELECTION& aSel )
266 {
268 return false;
269
270 return true;
271 };
272
273 auto orientCondition =
274 []( const SELECTION& aSel )
275 {
277 return false;
278
280 };
281
282 auto propertiesCondition =
283 [&]( const SELECTION& aSel )
284 {
285 if( aSel.GetSize() == 0 )
286 {
288 {
291
292 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
293 return true;
294 }
295
296 return false;
297 }
298
299 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
300 const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
301
302 if( !firstItem || !eeSelection )
303 return false;
304
305 switch( firstItem->Type() )
306 {
307 case SCH_SYMBOL_T:
308 case SCH_SHEET_T:
309 case SCH_SHEET_PIN_T:
310 case SCH_TEXT_T:
311 case SCH_TEXTBOX_T:
312 case SCH_TABLE_T:
313 case SCH_TABLECELL_T:
314 case SCH_LABEL_T:
316 case SCH_HIER_LABEL_T:
318 case SCH_RULE_AREA_T:
319 case SCH_FIELD_T:
320 case SCH_SHAPE_T:
321 case SCH_BITMAP_T:
322 return aSel.GetSize() == 1;
323
324 case SCH_LINE_T:
326 case SCH_JUNCTION_T:
327 if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
328 [&]( const EDA_ITEM* item )
329 {
330 return item->Type() == SCH_LINE_T
331 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
332 } ) )
333 {
334 return true;
335 }
336 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
337 [&]( const EDA_ITEM* item )
338 {
339 return item->Type() == SCH_JUNCTION_T;
340 } ) )
341 {
342 return true;
343 }
344 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
345 [&]( const EDA_ITEM* item )
346 {
347 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
348
349 wxCHECK( schItem, false );
350
351 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
352 || item->Type() == SCH_JUNCTION_T;
353 } ) )
354 {
355 return true;
356 }
357
358 return false;
359
360 default:
361 return false;
362 }
363 };
364
365 auto autoplaceCondition =
366 []( const SELECTION& aSel )
367 {
368 for( const EDA_ITEM* item : aSel )
369 {
370 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
371 return true;
372 }
373
374 return false;
375 };
376
377 // allTextTypes does not include SCH_SHEET_PIN_T because one cannot convert other
378 // types to/from this type, living only in a SHEET
379 static std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
385
386 auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
387
388 auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_DIRECTIVE_LABEL_T,
392 SCH_TEXTBOX_T } ) )
393 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
394
395 auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
399 SCH_TEXTBOX_T } ) )
400 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
401
402 auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
406 SCH_TEXTBOX_T } ) )
407 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
408
409 auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
413 SCH_TEXTBOX_T } ) )
414 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
415
416 auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
420 SCH_TEXTBOX_T } ) )
421 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
422
423 auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
427 SCH_TEXT_T } ) )
428 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
429
430 auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_BUS_WIRE_ENTRY_T,
432
433 auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
434
435 auto makeSymbolUnitMenu =
436 [&]( TOOL_INTERACTIVE* tool )
437 {
438 std::shared_ptr<SYMBOL_UNIT_MENU> menu = std::make_shared<SYMBOL_UNIT_MENU>();
439 menu->SetTool( tool );
440 tool->GetToolMenu().RegisterSubMenu( menu );
441 return menu.get();
442 };
443
444 auto makePinFunctionMenu =
445 [&]( TOOL_INTERACTIVE* tool )
446 {
447 std::shared_ptr<ALT_PIN_FUNCTION_MENU> menu = std::make_shared<ALT_PIN_FUNCTION_MENU>();
448 menu->SetTool( tool );
449 tool->GetToolMenu().RegisterSubMenu( menu );
450 return menu.get();
451 };
452
453 auto makePinTricksMenu =
454 [&]( TOOL_INTERACTIVE* tool )
455 {
456 std::shared_ptr<PIN_TRICKS_MENU> menu = std::make_shared<PIN_TRICKS_MENU>();
457 menu->SetTool( tool );
458 tool->GetToolMenu().RegisterSubMenu( menu );
459 return menu.get();
460 };
461
462 auto makeTransformMenu =
463 [&]()
464 {
465 CONDITIONAL_MENU* menu = new CONDITIONAL_MENU( moveTool );
466 menu->SetTitle( _( "Transform Selection" ) );
467
468 menu->AddItem( EE_ACTIONS::rotateCCW, orientCondition );
469 menu->AddItem( EE_ACTIONS::rotateCW, orientCondition );
470 menu->AddItem( EE_ACTIONS::mirrorV, orientCondition );
471 menu->AddItem( EE_ACTIONS::mirrorH, orientCondition );
472
473 return menu;
474 };
475
476 auto makeAttributesMenu =
477 [&]()
478 {
479 CONDITIONAL_MENU* menu = new CONDITIONAL_MENU( moveTool );
480 menu->SetTitle( _( "Attributes" ) );
481
485
486 menu->AddSeparator();
490
491 menu->AddSeparator();
495
496 menu->AddSeparator();
500
501 return menu;
502 };
503
504 auto makeEditFieldsMenu =
505 [&]()
506 {
508 menu->SetTitle( _( "Edit Main Fields" ) );
509
513
514 return menu;
515 };
516
517 auto makeConvertToMenu =
518 [&]()
519 {
521 menu->SetTitle( _( "Change To" ) );
522 menu->SetIcon( BITMAPS::right );
523
524 menu->AddItem( EE_ACTIONS::toLabel, toLabelCondition );
525 menu->AddItem( EE_ACTIONS::toCLabel, toCLabelCondition );
526 menu->AddItem( EE_ACTIONS::toHLabel, toHLabelCondition );
527 menu->AddItem( EE_ACTIONS::toGLabel, toGLabelCondition );
528 menu->AddItem( EE_ACTIONS::toText, toTextCondition );
529 menu->AddItem( EE_ACTIONS::toTextBox, toTextBoxCondition );
530
531 return menu;
532 };
533
534 //
535 // Add edit actions to the move tool menu
536 //
537 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
538
539 moveMenu.AddSeparator();
540 moveMenu.AddMenu( makeSymbolUnitMenu( moveTool ), E_C::SingleMultiUnitSymbol, 1 );
541
542 moveMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
543 moveMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
545 moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
546 moveMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
547
548 moveMenu.AddSeparator();
552 moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
553
554 //
555 // Add editing actions to the drawing tool menu
556 //
557 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
558
559 drawMenu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
560 drawMenu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
561
562 drawMenu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
563 drawMenu.AddSeparator( sheetSelection && EE_CONDITIONS::Idle, 1 );
564
565 drawMenu.AddMenu( makeSymbolUnitMenu( drawingTools ), E_C::SingleMultiUnitSymbol, 1 );
566
567 drawMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
568 drawMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
569 drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
570 drawMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
571 drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
572
574
575 drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
576 drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
577 drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
578 drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
579 drawMenu.AddItem( EE_ACTIONS::toTextBox, anyTextTool && E_C::Idle, 200 );
580
581 //
582 // Add editing actions to the selection tool menu
583 //
585
586 selToolMenu.AddMenu( makeSymbolUnitMenu( m_selectionTool ), E_C::SingleMultiUnitSymbol, 1 );
587 selToolMenu.AddMenu( makePinFunctionMenu( m_selectionTool ), E_C::SingleMultiFunctionPin, 1 );
588 selToolMenu.AddMenu( makePinTricksMenu( m_selectionTool ), E_C::AllPins, 1 );
589
590 selToolMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
591 selToolMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
593 selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
594 selToolMenu.AddMenu( makeEditFieldsMenu(), E_C::SingleSymbol, 200 );
595 selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
596
602 selToolMenu.AddMenu( makeConvertToMenu(), toChangeCondition, 200 );
603
604 selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
605
606 selToolMenu.AddSeparator( 300 );
607 selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
608 selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
609 selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
610 selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
611 selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
612 selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
613
614 selToolMenu.AddSeparator( 400 );
615 selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
616 selToolMenu.AddItem( ACTIONS::unselectAll, hasElements, 400 );
617
618 return true;
619}
620
621
622const std::vector<KICAD_T> SCH_EDIT_TOOL::RotatableItems = {
628 SCH_TABLECELL_T, // will be promoted to parent table(s)
643};
644
645
647{
648 bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
650
651 if( selection.GetSize() == 0 )
652 return 0;
653
654 SCH_ITEM* head = nullptr;
655 int principalItemCount = 0; // User-selected items (as opposed to connected wires)
656 VECTOR2I rotPoint;
657 bool moving = false;
658 SCH_COMMIT localCommit( m_toolMgr );
659 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
660
661 if( !commit )
662 commit = &localCommit;
663
664 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
665 {
666 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
667
668 if( item->HasFlag( SELECTED_BY_DRAG ) )
669 continue;
670
671 principalItemCount++;
672
673 if( !head )
674 head = item;
675 }
676
677 if( head && head->IsMoving() )
678 moving = true;
679
680 if( principalItemCount == 1 )
681 {
682 if( moving && selection.HasReferencePoint() )
683 rotPoint = selection.GetReferencePoint();
684 else if( head->IsConnectable() )
685 rotPoint = head->GetPosition();
686 else
688
689 if( !moving )
690 commit->Modify( head, m_frame->GetScreen() );
691
692 switch( head->Type() )
693 {
694 case SCH_SYMBOL_T:
695 {
696 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
697
698 symbol->Rotate( rotPoint, !clockwise );
699
702
703 break;
704 }
705
706 case SCH_TEXT_T:
707 case SCH_LABEL_T:
709 case SCH_HIER_LABEL_T:
711 {
712 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
713 textItem->Rotate90( clockwise );
714 break;
715 }
716
717 case SCH_SHEET_PIN_T:
718 {
719 // Rotate pin within parent sheet
720 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
721 SCH_SHEET* sheet = pin->GetParent();
722
723 pin->Rotate( sheet->GetBoundingBox().GetCenter(), !clockwise );
724
725 break;
726 }
727
728 case SCH_LINE_T:
729 {
730 SCH_LINE* line = static_cast<SCH_LINE*>( head );
731
732 // Equal checks for both and neither. We need this because on undo
733 // the item will have both flags cleared, but will be selected, so it is possible
734 // for the user to get a selected line with neither endpoint selected. We
735 // set flags to make sure Rotate() works when we call it.
736 if( line->HasFlag( STARTPOINT ) == line->HasFlag( ENDPOINT ) )
737 {
738 line->SetFlags( STARTPOINT | ENDPOINT );
739
740 // When we allow off grid items, the rotPoint should be set to the midpoint
741 // of the line to allow rotation around the center, and the next if
742 // should become an else-if
743 }
744
745 if( line->HasFlag( STARTPOINT ) )
746 rotPoint = line->GetEndPoint();
747 else if( line->HasFlag( ENDPOINT ) )
748 rotPoint = line->GetStartPoint();
749 }
750
752 case SCH_JUNCTION_T:
753 case SCH_NO_CONNECT_T:
756 head->Rotate( rotPoint, !clockwise );
757
758 break;
759
760 case SCH_FIELD_T:
761 {
762 SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
763
764 if( field->GetTextAngle().IsHorizontal() )
766 else
768
769 // Now that we're moving a field, they're no longer autoplaced.
770 static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
771
772 break;
773 }
774
775 case SCH_RULE_AREA_T:
776 case SCH_SHAPE_T:
777 case SCH_TEXTBOX_T:
778 head->Rotate( rotPoint, !clockwise );
779
780 break;
781
782 case SCH_TABLE_T:
783 {
784 // Rotate the table on itself. Tables do not have an anchor point.
785 SCH_TABLE* table = static_cast<SCH_TABLE*>( head );
786 BOX2I box( table->GetPosition(), table->GetEnd() - table->GetPosition() );
787 rotPoint = m_frame->GetNearestHalfGridPosition( box.GetCenter() );
788
789 head->Rotate( rotPoint, !clockwise );
790
791 break;
792 }
793
794 case SCH_BITMAP_T:
795 head->Rotate( rotPoint, !clockwise );
796
797 // The bitmap is cached in Opengl: clear the cache to redraw
799 break;
800
801 case SCH_SHEET_T:
802 {
803 // Rotate the sheet on itself. Sheets do not have an anchor point.
804 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
805
807 sheet->Rotate( rotPoint, !clockwise );
808
809 break;
810 }
811
812 default:
813 UNIMPLEMENTED_FOR( head->GetClass() );
814 }
815
816 m_frame->UpdateItem( head, false, true );
817 }
818 else
819 {
820 if( moving && selection.HasReferencePoint() )
821 rotPoint = selection.GetReferencePoint();
822 else
823 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
824 }
825
826 for( EDA_ITEM* edaItem : selection )
827 {
828 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
829
830 // We've already rotated the user selected item if there was only one. We're just
831 // here to rotate the ends of wires that were attached to it.
832 if( principalItemCount == 1 && !item->HasFlag( SELECTED_BY_DRAG ) )
833 continue;
834
835 if( !moving )
836 commit->Modify( item, m_frame->GetScreen() );
837
838 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
839 {
840 if( item->Type() == SCH_LINE_T )
841 {
842 SCH_LINE* line = (SCH_LINE*) item;
843
844 // If we are rotating more than one item, we do not have start/end
845 // points separately selected
846 if( item->HasFlag( STARTPOINT ) )
847 line->RotateStart( rotPoint );
848
849 if( item->HasFlag( ENDPOINT ) )
850 line->RotateEnd( rotPoint );
851 }
852 else if( item->Type() == SCH_SHEET_PIN_T )
853 {
854 if( item->GetParent()->IsSelected() )
855 {
856 // parent will rotate us
857 }
858 else
859 {
860 // rotate within parent
861 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
862 SCH_SHEET* sheet = pin->GetParent();
863
864 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter(), false );
865 }
866 }
867 else if( item->Type() == SCH_FIELD_T )
868 {
869 if( item->GetParent()->IsSelected() )
870 {
871 // parent will rotate us
872 }
873 else
874 {
875 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
876
877 field->Rotate( rotPoint, false );
878
879 if( field->GetTextAngle().IsHorizontal() )
881 else
883
884 // Now that we're moving a field, they're no longer autoplaced.
885 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
886 }
887 }
888 else
889 {
890 item->Rotate( rotPoint, false );
891 }
892 }
893
894 m_frame->UpdateItem( item, false, true );
895 updateItem( item, true );
896 }
897
898 if( moving )
899 {
901 }
902 else
903 {
904 EE_SELECTION selectionCopy = selection;
905
906 if( selection.IsHover() )
908
910 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
911 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
912
913 m_frame->SchematicCleanUp( commit );
914
915 if( !localCommit.Empty() )
916 localCommit.Push( _( "Rotate" ) );
917 }
918
919 return 0;
920}
921
922
924{
926
927 if( selection.GetSize() == 0 )
928 return 0;
929
930 bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
931 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
932 bool connections = false;
933 bool moving = item->IsMoving();
934 SCH_COMMIT localCommit( m_toolMgr );
935 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
936
937 if( !commit )
938 commit = &localCommit;
939
940 if( selection.GetSize() == 1 )
941 {
942 if( !moving )
943 commit->Modify( item, m_frame->GetScreen() );
944
945 switch( item->Type() )
946 {
947 case SCH_SYMBOL_T:
948 {
949 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
950
951 if( vertical )
952 symbol->SetOrientation( SYM_MIRROR_X );
953 else
954 symbol->SetOrientation( SYM_MIRROR_Y );
955
956 symbol->ClearFieldsAutoplaced();
957 break;
958 }
959
960 case SCH_TEXT_T:
961 case SCH_LABEL_T:
963 case SCH_HIER_LABEL_T:
965 {
966 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
967 textItem->MirrorSpinStyle( !vertical );
968 break;
969 }
970
971 case SCH_SHEET_PIN_T:
972 {
973 // mirror within parent sheet
974 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
975 SCH_SHEET* sheet = pin->GetParent();
976
977 if( vertical )
978 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
979 else
980 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
981
982 break;
983 }
984
985 case SCH_FIELD_T:
986 {
987 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
988
989 if( vertical )
990 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
991 else
992 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
993
994 // Now that we're re-justifying a field, they're no longer autoplaced.
995 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
996
997 break;
998 }
999
1000 case SCH_BITMAP_T:
1001 if( vertical )
1002 item->MirrorVertically( item->GetPosition().y );
1003 else
1004 item->MirrorHorizontally( item->GetPosition().x );
1005
1006 // The bitmap is cached in Opengl: clear the cache to redraw
1008 break;
1009
1010 case SCH_SHEET_T:
1011 {
1012 // Mirror the sheet on itself. Sheets do not have a anchor point.
1014
1015 if( vertical )
1016 item->MirrorVertically( mirrorPoint.y );
1017 else
1018 item->MirrorHorizontally( mirrorPoint.x );
1019
1020 break;
1021 }
1022
1023 default:
1024 if( vertical )
1025 item->MirrorVertically( item->GetPosition().y );
1026 else
1027 item->MirrorHorizontally( item->GetPosition().x );
1028
1029 break;
1030 }
1031
1032 connections = item->IsConnectable();
1033 m_frame->UpdateItem( item, false, true );
1034 }
1035 else if( selection.GetSize() > 1 )
1036 {
1037 VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
1038
1039 for( EDA_ITEM* edaItem : selection )
1040 {
1041 item = static_cast<SCH_ITEM*>( edaItem );
1042
1043 if( !moving )
1044 commit->Modify( item, m_frame->GetScreen() );
1045
1046 if( item->Type() == SCH_SHEET_PIN_T )
1047 {
1048 if( item->GetParent()->IsSelected() )
1049 {
1050 // parent will mirror us
1051 }
1052 else
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 }
1064 else if( item->Type() == SCH_FIELD_T )
1065 {
1066 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1067
1068 if( vertical )
1069 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
1070 else
1071 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
1072
1073 // Now that we're re-justifying a field, they're no longer autoplaced.
1074 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1075 }
1076 else
1077 {
1078 if( vertical )
1079 item->MirrorVertically( mirrorPoint.y );
1080 else
1081 item->MirrorHorizontally( mirrorPoint.x );
1082 }
1083
1084 connections |= item->IsConnectable();
1085 m_frame->UpdateItem( item, false, true );
1086 }
1087 }
1088
1089 // Update R-Tree for modified items
1090 for( EDA_ITEM* selected : selection )
1091 updateItem( selected, true );
1092
1093 if( item->IsMoving() )
1094 {
1096 }
1097 else
1098 {
1099 EE_SELECTION selectionCopy = selection;
1100
1101 if( selection.IsHover() )
1103
1104 if( connections )
1105 {
1107 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
1108 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
1109
1110 m_frame->SchematicCleanUp( commit );
1111 }
1112
1113 if( !localCommit.Empty() )
1114 localCommit.Push( _( "Mirror" ) );
1115 }
1116
1117 return 0;
1118}
1119
1120
1121const std::vector<KICAD_T> swappableItems = {
1124 SCH_TEXT_T,
1137};
1138
1139
1141{
1143 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
1144
1145 // Sheet pins are special, we need to make sure if we have any sheet pins,
1146 // that we only have sheet pins, and that they have the same parent
1147 if( selection.CountType( SCH_SHEET_PIN_T ) > 0 )
1148 {
1149 if( !selection.OnlyContains( { SCH_SHEET_PIN_T } ) )
1150 return 0;
1151
1152 SCH_SHEET_PIN* firstPin = static_cast<SCH_SHEET_PIN*>( selection.Front() );
1153 SCH_SHEET* parent = firstPin->GetParent();
1154
1155 for( EDA_ITEM* item : selection )
1156 {
1157 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1158
1159 if( pin->GetParent() != parent )
1160 return 0;
1161 }
1162 }
1163
1164 if( selection.Size() < 2 )
1165 return 0;
1166
1167 bool isMoving = selection.Front()->IsMoving();
1168 bool appendUndo = isMoving;
1169 bool connections = false;
1170
1171 SCH_SCREEN* screen = this->m_frame->GetScreen();
1172
1173 for( size_t i = 0; i < sorted.size() - 1; i++ )
1174 {
1175 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
1176 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
1177
1178 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
1179 std::swap( aPos, bPos );
1180
1181 saveCopyInUndoList( a, UNDO_REDO::CHANGED, appendUndo );
1182 appendUndo = true;
1183 saveCopyInUndoList( b, UNDO_REDO::CHANGED, appendUndo );
1184
1185 // Sheet pins need to have their sides swapped before we change their
1186 // positions
1187 if( a->Type() == SCH_SHEET_PIN_T )
1188 {
1189 SCH_SHEET_PIN* aPin = static_cast<SCH_SHEET_PIN*>( a );
1190 SCH_SHEET_PIN* bPin = static_cast<SCH_SHEET_PIN*>( b );
1191 SHEET_SIDE aSide = aPin->GetSide(), bSide = bPin->GetSide();
1192 std::swap( aSide, bSide );
1193 aPin->SetSide( aSide );
1194 bPin->SetSide( bSide );
1195 }
1196
1197 a->SetPosition( aPos );
1198 b->SetPosition( bPos );
1199
1200 if( a->Type() == b->Type() )
1201 {
1202 switch( a->Type() )
1203 {
1204 case SCH_LABEL_T:
1205 case SCH_GLOBAL_LABEL_T:
1206 case SCH_HIER_LABEL_T:
1208 m_frame->AutoRotateItem( screen, a );
1209 m_frame->AutoRotateItem( screen, b );
1210 break;
1211 case SCH_SYMBOL_T:
1212 {
1213 SCH_SYMBOL* aSymbol = static_cast<SCH_SYMBOL*>( a );
1214 SCH_SYMBOL* bSymbol = static_cast<SCH_SYMBOL*>( b );
1215 int aOrient = aSymbol->GetOrientation(), bOrient = bSymbol->GetOrientation();
1216 std::swap( aOrient, bOrient );
1217 aSymbol->SetOrientation( aOrient );
1218 bSymbol->SetOrientation( bOrient );
1219 break;
1220 }
1221 default: break;
1222 }
1223 }
1224
1225 connections |= a->IsConnectable();
1226 connections |= b->IsConnectable();
1227 m_frame->UpdateItem( a, false, true );
1228 m_frame->UpdateItem( b, false, true );
1229 }
1230
1231 // Update R-Tree for modified items
1232 for( EDA_ITEM* selected : selection )
1233 updateItem( selected, true );
1234
1235 if( isMoving )
1236 {
1238 }
1239 else
1240 {
1241 if( selection.IsHover() )
1243
1244 if( connections )
1246
1247 m_frame->OnModify();
1248 }
1249
1250 return 0;
1251}
1252
1253
1255{
1256 const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
1257
1258 if( sourceItems.empty() )
1259 return 0;
1260
1262
1263 SCH_COMMIT commit( m_toolMgr );
1264 EE_SELECTION newItems;
1265
1266 for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
1267 {
1268 SCH_ITEM* newItem = item->Duplicate();
1270 bool restore_state = false;
1271
1272 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
1273 {
1274 // If incrementing tries to go below zero, tell user why the value is repeated
1275
1276 if( !label->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
1277 m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
1278 }
1279
1280 // If cloning a symbol then put into 'move' mode.
1281 if( newItem->Type() == SCH_SYMBOL_T )
1282 {
1283 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
1284 newItem->Move( cursorPos - newItem->GetPosition() );
1285 }
1286 else
1287 {
1290 }
1291
1292 // If cloning a sheet, check that we aren't going to create recursion
1293 if( newItem->Type() == SCH_SHEET_T )
1294 {
1295 SCH_SHEET_PATH* currentSheet = &m_frame->GetCurrentSheet();
1296 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( newItem );
1297
1298 if( m_frame->CheckSheetForRecursion( sheet, currentSheet ) )
1299 {
1300 // Clear out the filename so that the user can pick a new one
1301 sheet->SetFileName( wxEmptyString );
1302 sheet->GetScreen()->SetFileName( wxEmptyString );
1303 restore_state = !m_frame->EditSheetProperties( sheet, currentSheet, nullptr );
1304 }
1305 }
1306
1308 newItem->SetFlags( IS_NEW );
1309 m_frame->AddToScreen( newItem, m_frame->GetScreen() );
1310 commit.Added( newItem, m_frame->GetScreen() );
1311
1312 if( newItem->Type() == SCH_SYMBOL_T )
1313 {
1315 SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
1316 int annotateStartNum = projSettings.m_AnnotateStartNum;
1317
1318 if( annotate.automatic )
1319 {
1320 static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
1321 NULL_REPORTER reporter;
1323 (ANNOTATE_ORDER_T) annotate.sort_order,
1324 (ANNOTATE_ALGO_T) annotate.method, true /* recursive */,
1325 annotateStartNum, false, false, reporter );
1326 }
1327
1328 restore_state = !m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit );
1329 }
1330
1331 if( restore_state )
1332 {
1333 commit.Revert();
1334 }
1335 else
1336 {
1337 newItems.Add( newItem );
1338
1340 lwbTool->TrimOverLappingWires( &commit, &newItems );
1341 lwbTool->AddJunctionsIfNeeded( &commit, &newItems );
1342
1343 m_frame->SchematicCleanUp( &commit );
1344 commit.Push( _( "Repeat Item" ) );
1345 }
1346
1347 }
1348
1349 if( !newItems.Empty() )
1350 m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
1351
1352 for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
1353 m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
1354
1355 return 0;
1356}
1357
1358
1359static std::vector<KICAD_T> deletableItems =
1360{
1363 SCH_LINE_T,
1368 SCH_TEXT_T,
1370 SCH_TABLECELL_T, // Clear contents
1380 SCH_FIELD_T, // Will be hidden
1382};
1383
1384
1386{
1387 SCH_SCREEN* screen = m_frame->GetScreen();
1388 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection( deletableItems ).GetItems();
1389 SCH_COMMIT commit( m_toolMgr );
1390 std::vector<VECTOR2I> pts;
1391 bool updateHierarchy = false;
1392
1393 if( items.empty() )
1394 return 0;
1395
1396 // Don't leave a freed pointer in the selection
1398
1399 for( EDA_ITEM* item : items )
1400 item->ClearFlags( STRUCT_DELETED );
1401
1402 for( EDA_ITEM* item : items )
1403 {
1404 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1405
1406 if( !sch_item )
1407 continue;
1408
1409 if( sch_item->IsConnectable() )
1410 {
1411 std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
1412 pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1413 }
1414
1415 if( sch_item->Type() == SCH_JUNCTION_T )
1416 {
1417 sch_item->SetFlags( STRUCT_DELETED );
1418 // clean up junctions at the end
1419 }
1420 else if( sch_item->Type() == SCH_SHEET_PIN_T )
1421 {
1422 SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1423 SCH_SHEET* sheet = pin->GetParent();
1424
1425 if( !alg::contains( items, sheet ) )
1426 {
1427 commit.Modify( sheet, m_frame->GetScreen() );
1428 sheet->RemovePin( pin );
1429 }
1430 }
1431 else if( sch_item->Type() == SCH_FIELD_T )
1432 {
1433 // Hide field
1434 commit.Modify( item, m_frame->GetScreen() );
1435 static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
1436 }
1437 else if( sch_item->Type() == SCH_TABLECELL_T )
1438 {
1439 // Clear contents of table cell
1440 commit.Modify( item, m_frame->GetScreen() );
1441 static_cast<SCH_TABLECELL*>( sch_item )->SetText( wxEmptyString );
1442 }
1443 else if( sch_item->Type() == SCH_RULE_AREA_T )
1444 {
1445 sch_item->SetFlags( STRUCT_DELETED );
1446 commit.Remove( item, m_frame->GetScreen() );
1447 }
1448 else
1449 {
1450 sch_item->SetFlags( STRUCT_DELETED );
1451 commit.Remove( item, m_frame->GetScreen() );
1452 updateHierarchy |= ( sch_item->Type() == SCH_SHEET_T );
1453 }
1454 }
1455
1456 for( const VECTOR2I& point : pts )
1457 {
1458 SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1459
1460 if( !junction )
1461 continue;
1462
1463 if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1464 m_frame->DeleteJunction( &commit, junction );
1465 }
1466
1467 commit.Push( _( "Delete" ) );
1468
1469 if( updateHierarchy )
1471
1472 return 0;
1473}
1474
1475
1476#define HITTEST_THRESHOLD_PIXELS 5
1477
1478
1480{
1482
1484 m_pickerItem = nullptr;
1485
1486 // Deactivate other tools; particularly important if another PICKER is currently running
1487 Activate();
1488
1489 picker->SetCursor( KICURSOR::REMOVE );
1490 picker->SetSnapping( false );
1491
1492 picker->SetClickHandler(
1493 [this]( const VECTOR2D& aPosition ) -> bool
1494 {
1495 if( m_pickerItem )
1496 {
1498 selectionTool->UnbrightenItem( m_pickerItem );
1499 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1501 m_pickerItem = nullptr;
1502 }
1503
1504 return true;
1505 } );
1506
1507 picker->SetMotionHandler(
1508 [this]( const VECTOR2D& aPos )
1509 {
1510 EE_COLLECTOR collector;
1511 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1512 collector.Collect( m_frame->GetScreen(), deletableItems, aPos );
1513
1515 selectionTool->GuessSelectionCandidates( collector, aPos );
1516
1517 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1518
1519 if( m_pickerItem != item )
1520 {
1521 if( m_pickerItem )
1522 selectionTool->UnbrightenItem( m_pickerItem );
1523
1524 m_pickerItem = item;
1525
1526 if( m_pickerItem )
1527 selectionTool->BrightenItem( m_pickerItem );
1528 }
1529 } );
1530
1531 picker->SetFinalizeHandler(
1532 [this]( const int& aFinalState )
1533 {
1534 if( m_pickerItem )
1535 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
1536
1537 // Wake the selection tool after exiting to ensure the cursor gets updated
1539 } );
1540
1542
1543 return 0;
1544}
1545
1546
1548{
1549 KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1550 SCH_COMMIT commit( m_toolMgr );
1551
1552 // Save old symbol in undo list if not already in edit, or moving.
1553 if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1554 commit.Modify( aField, m_frame->GetScreen() );
1555
1556 if( parentType == SCH_SYMBOL_T && aField->GetId() == REFERENCE_FIELD )
1557 static_cast<SCH_ITEM*>( aField->GetParent() )->SetConnectivityDirty();
1558
1559 wxString caption;
1560
1561 // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1562 if( parentType == SCH_SYMBOL_T && aField->IsMandatory() )
1563 {
1564 wxString translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(),
1565 DO_TRANSLATE );
1566 caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
1567 }
1568 else if( parentType == SCH_SHEET_T && aField->IsMandatory() )
1569 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1570 else
1571 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1572
1573 DIALOG_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1574
1575 // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1576 if( dlg.ShowQuasiModal() != wxID_OK )
1577 return;
1578
1579 dlg.UpdateField( &commit, aField, &m_frame->GetCurrentSheet() );
1580
1581 if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1582 static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1583
1584 if( !commit.Empty() )
1585 commit.Push( caption );
1586}
1587
1588
1590{
1592
1593 if( sel.Size() != 1 )
1594 return 0;
1595
1596 bool clearSelection = sel.IsHover();
1597 EDA_ITEM* item = sel.Front();
1598
1599 if( item->Type() == SCH_FIELD_T )
1600 {
1601 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1602
1603 if( ( aEvent.IsAction( &EE_ACTIONS::editReference ) && field->GetId() != REFERENCE_FIELD )
1604 || ( aEvent.IsAction( &EE_ACTIONS::editValue ) && field->GetId() != VALUE_FIELD )
1605 || ( aEvent.IsAction( &EE_ACTIONS::editFootprint ) && field->GetId() != FOOTPRINT_FIELD ) )
1606 {
1607 item = field->GetParentSymbol();
1610 }
1611 }
1612
1613 if( item->Type() == SCH_SYMBOL_T )
1614 {
1615 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1616
1617 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1618 {
1620 }
1621 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1622 {
1623 editFieldText( symbol->GetField( VALUE_FIELD ) );
1624 }
1625 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1626 {
1627 if( !symbol->IsPower() )
1629 }
1630 }
1631 else if( item->Type() == SCH_FIELD_T )
1632 {
1633 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1634
1635 editFieldText( field );
1636
1637 if( !field->IsVisible() )
1638 clearSelection = true;
1639 }
1640
1641 if( clearSelection )
1643
1644 return 0;
1645}
1646
1647
1649{
1651 SCH_COMMIT commit( m_toolMgr );
1652 SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1653 bool moving = head && head->IsMoving();
1654
1655 if( selection.Empty() )
1656 return 0;
1657
1658 std::vector<SCH_ITEM*> autoplaceItems;
1659
1660 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1661 {
1662 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1663
1664 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
1665 autoplaceItems.push_back( item );
1666 else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
1667 autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
1668 }
1669
1670 for( SCH_ITEM* sch_item : autoplaceItems )
1671 {
1672 if( !moving && !sch_item->IsNew() )
1673 commit.Modify( sch_item, m_frame->GetScreen() );
1674
1675 sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1676
1677 updateItem( sch_item, true );
1678 }
1679
1680 if( moving )
1681 {
1683 }
1684 else
1685 {
1686 if( !commit.Empty() )
1687 commit.Push( _( "Autoplace Fields" ) );
1688
1689 if( selection.IsHover() )
1691 }
1692
1693 return 0;
1694}
1695
1696
1698{
1699 SCH_SYMBOL* selectedSymbol = nullptr;
1701
1702 if( !selection.Empty() )
1703 selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1704
1706
1707 if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1708 || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1709 {
1711 }
1712
1713 DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1714
1715 // QuasiModal required to invoke symbol browser
1716 dlg.ShowQuasiModal();
1717
1718 return 0;
1719}
1720
1721
1723{
1725
1726 if( selection.Empty() )
1727 return 0;
1728
1729 SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1730
1732 && symbol->GetBodyStyle() == BODY_STYLE::BASE )
1733 {
1734 return 0;
1735 }
1736
1738 && symbol->GetBodyStyle() == BODY_STYLE::DEMORGAN )
1739 {
1740 return 0;
1741 }
1742
1743 SCH_COMMIT commit( m_toolMgr );
1744
1745 if( !symbol->IsNew() )
1746 commit.Modify( symbol, m_frame->GetScreen() );
1747
1748 m_frame->FlipBodyStyle( symbol );
1749
1750 if( symbol->IsNew() )
1752
1753 if( !commit.Empty() )
1754 commit.Push( _( "Change Body Style" ) );
1755
1756 if( selection.IsHover() )
1758
1759 return 0;
1760}
1761
1762
1764{
1766 bool clearSelection = selection.IsHover();
1767
1768 if( selection.Empty() )
1769 {
1770 if( getView()->IsLayerVisible( LAYER_SCHEMATIC_DRAWINGSHEET ) )
1771 {
1773 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1774
1775 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1777 }
1778
1779 return 0;
1780 }
1781
1782 EDA_ITEM* curr_item = selection.Front();
1783
1784 switch( curr_item->Type() )
1785 {
1786 case SCH_LINE_T:
1788 case SCH_JUNCTION_T:
1789 case SCH_TABLECELL_T:
1790 break;
1791
1792 default:
1793 if( selection.Size() > 1 )
1794 return 0;
1795
1796 break;
1797 }
1798
1799 switch( curr_item->Type() )
1800 {
1801 case SCH_SYMBOL_T:
1802 {
1803 int retval;
1804 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( curr_item );
1805
1806 // This needs to be scoped so the dialog destructor removes blocking status
1807 // before we launch the next dialog.
1808 {
1809 DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1810
1811 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1812 // frame. Therefore this dialog as a modal frame parent, MUST be run under
1813 // quasimodal mode for the quasimodal frame support to work. So don't use
1814 // the QUASIMODAL macros here.
1815 retval = symbolPropsDialog.ShowQuasiModal();
1816 }
1817
1818 if( retval == SYMBOL_PROPS_EDIT_OK )
1819 {
1822
1823 m_frame->OnModify();
1824 }
1825 else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1826 {
1828 true );
1829
1830 wxCHECK( editor, 0 );
1831
1832 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1833 blocking_win->Close( true );
1834
1835 // The broken library symbol link indicator cannot be edited.
1836 if( symbol->IsMissingLibSymbol() )
1837 return 0;
1838
1839 editor->LoadSymbolFromSchematic( symbol );
1840
1841 editor->Show( true );
1842 editor->Raise();
1843 }
1844 else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1845 {
1847 true );
1848
1849 wxCHECK( editor, 0 );
1850
1851 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1852 blocking_win->Close( true );
1853
1854 editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetBodyStyle() );
1855
1856 editor->Show( true );
1857 editor->Raise();
1858 }
1859 else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1860 {
1862 dlg.ShowQuasiModal();
1863 }
1864 else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1865 {
1867 dlg.ShowQuasiModal();
1868 }
1869
1870 break;
1871 }
1872
1873 case SCH_SHEET_T:
1874 {
1875 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( curr_item );
1876 bool doClearAnnotation;
1877 bool doRefresh = false;
1878 bool updateHierarchyNavigator = false;
1879
1880 // Keep track of existing sheet paths. EditSheet() can modify this list.
1881 // Note that we use the validity checking/repairing version here just to make sure
1882 // we've got a valid hierarchy to begin with.
1883 SCH_SHEET_LIST originalHierarchy( &m_frame->Schematic().Root(), true );
1884
1885 doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1886 &doClearAnnotation, &updateHierarchyNavigator );
1887
1888 // If the sheet file is changed and new sheet contents are loaded then we have to
1889 // clear the annotations on the new content (as it may have been set from some other
1890 // sheet path reference)
1891 if( doClearAnnotation )
1892 {
1893 SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1894
1895 // We clear annotation of new sheet paths here:
1896 screensList.ClearAnnotationOfNewSheetPaths( originalHierarchy );
1897
1898 // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1899 // path, but symbols managed by its sheet path must have their annotation cleared
1900 // because they are new:
1901 sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet(), false );
1902 }
1903
1904 if( doRefresh )
1906
1907 if( updateHierarchyNavigator )
1909
1910 break;
1911 }
1912
1913 case SCH_SHEET_PIN_T:
1914 {
1915 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( curr_item );
1917
1918 // QuasiModal required for help dialog
1919 dlg.ShowQuasiModal();
1920 break;
1921 }
1922
1923 case SCH_TEXT_T:
1924 case SCH_TEXTBOX_T:
1925 {
1926 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
1927
1928 // QuasiModal required for syntax help and Scintilla auto-complete
1929 dlg.ShowQuasiModal();
1930 break;
1931 }
1932
1933 case SCH_TABLECELL_T:
1934 if( SELECTION_CONDITIONS::OnlyTypes( { SCH_TABLECELL_T } )( selection ) )
1935 {
1936 std::vector<SCH_TABLECELL*> cells;
1937
1938 for( EDA_ITEM* item : selection.Items() )
1939 cells.push_back( static_cast<SCH_TABLECELL*>( item ) );
1940
1942
1943 dlg.ShowModal();
1944
1946 {
1947 SCH_TABLE* table = static_cast<SCH_TABLE*>( cells[0]->GetParent() );
1948 DIALOG_TABLE_PROPERTIES tableDlg( m_frame, table );
1949
1950 tableDlg.ShowModal();
1951 }
1952 }
1953
1954 break;
1955
1956 case SCH_TABLE_T:
1957 {
1958 DIALOG_TABLE_PROPERTIES dlg( m_frame, static_cast<SCH_TABLE*>( curr_item ) );
1959
1960 // QuasiModal required for Scintilla auto-complete
1961 dlg.ShowQuasiModal();
1962 break;
1963 }
1964
1965 case SCH_LABEL_T:
1966 case SCH_GLOBAL_LABEL_T:
1967 case SCH_HIER_LABEL_T:
1969 {
1970 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( curr_item ) );
1971
1972 // QuasiModal for syntax help and Scintilla auto-complete
1973 dlg.ShowQuasiModal();
1974 break;
1975 }
1976
1977 case SCH_FIELD_T:
1978 {
1979 SCH_FIELD* field = static_cast<SCH_FIELD*>( curr_item );
1980
1981 editFieldText( field );
1982
1983 if( !field->IsVisible() )
1984 clearSelection = true;
1985
1986 break;
1987 }
1988
1989 case SCH_SHAPE_T:
1990 {
1991 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
1992
1993 dlg.ShowModal();
1994 break;
1995 }
1996
1997 case SCH_BITMAP_T:
1998 {
1999 SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( curr_item );
2000 DIALOG_IMAGE_PROPERTIES dlg( m_frame, bitmap );
2001
2002 if( dlg.ShowModal() == wxID_OK )
2003 {
2004 // The bitmap is cached in Opengl: clear the cache in case it has become invalid
2006 }
2007
2008 break;
2009 }
2010
2011 case SCH_RULE_AREA_T:
2012 {
2013 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
2014 dlg.SetTitle( _( "Rule Area Properties" ) );
2015
2016 dlg.ShowModal();
2017 break;
2018 }
2019
2020 case SCH_LINE_T:
2022 case SCH_JUNCTION_T:
2024 {
2025 std::deque<SCH_LINE*> lines;
2026
2027 for( EDA_ITEM* selItem : selection.Items() )
2028 lines.push_back( static_cast<SCH_LINE*>( selItem ) );
2029
2030 DIALOG_LINE_PROPERTIES dlg( m_frame, lines );
2031
2032 dlg.ShowModal();
2033 }
2034 else if( SELECTION_CONDITIONS::OnlyTypes( { SCH_JUNCTION_T } )( selection ) )
2035 {
2036 std::deque<SCH_JUNCTION*> junctions;
2037
2038 for( EDA_ITEM* selItem : selection.Items() )
2039 junctions.push_back( static_cast<SCH_JUNCTION*>( selItem ) );
2040
2041 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
2042
2043 dlg.ShowModal();
2044 }
2048 SCH_JUNCTION_T } )( selection ) )
2049 {
2050 std::deque<SCH_ITEM*> items;
2051
2052 for( EDA_ITEM* selItem : selection.Items() )
2053 items.push_back( static_cast<SCH_ITEM*>( selItem ) );
2054
2055 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, items );
2056
2057 dlg.ShowModal();
2058 }
2059 else
2060 {
2061 return 0;
2062 }
2063
2064 break;
2065
2066 case SCH_MARKER_T:
2067 if( SELECTION_CONDITIONS::OnlyTypes( { SCH_MARKER_T } )( selection ) )
2068 {
2070
2071 if( inspectionTool )
2072 inspectionTool->CrossProbe( static_cast<SCH_MARKER*> ( selection.Front() ) );
2073 }
2074 break;
2075
2076 case SCH_NO_CONNECT_T:
2077 case SCH_PIN_T:
2078 break;
2079
2080 default: // Unexpected item
2081 wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + curr_item->GetClass() );
2082 }
2083
2084 updateItem( curr_item, true );
2085
2086 if( clearSelection )
2088
2089 return 0;
2090}
2091
2092
2094{
2095 KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
2097 SCH_TEXT_T,
2098 SCH_TEXTBOX_T } );
2099 SCH_COMMIT commit( m_toolMgr );
2100
2101 for( unsigned int i = 0; i < selection.GetSize(); ++i )
2102 {
2103 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( selection.GetItem( i ) );
2104
2105 if( item && item->Type() != convertTo )
2106 {
2107 EDA_TEXT* sourceText = dynamic_cast<EDA_TEXT*>( item );
2108 bool selected = item->IsSelected();
2109 SCH_ITEM* newtext = nullptr;
2110 VECTOR2I position = item->GetPosition();
2111 wxString txt;
2112 wxString href;
2114 LABEL_FLAG_SHAPE shape = LABEL_FLAG_SHAPE::L_UNSPECIFIED;
2115
2116 switch( item->Type() )
2117 {
2118 case SCH_LABEL_T:
2119 case SCH_GLOBAL_LABEL_T:
2120 case SCH_HIER_LABEL_T:
2121 {
2122 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
2123
2124 txt = UnescapeString( label->GetText() );
2125 spinStyle = label->GetSpinStyle();
2126 shape = label->GetShape();
2127 href = label->GetHyperlink();
2128 break;
2129 }
2130
2132 {
2133 SCH_DIRECTIVE_LABEL* dirlabel = static_cast<SCH_DIRECTIVE_LABEL*>( item );
2134
2135 // a SCH_DIRECTIVE_LABEL has no text
2136 txt = _( "<empty>" );
2137
2138 spinStyle = dirlabel->GetSpinStyle();
2139 href = dirlabel->GetHyperlink();
2140 break;
2141 }
2142
2143 case SCH_TEXT_T:
2144 {
2145 SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
2146
2147 txt = text->GetText();
2148 href = text->GetHyperlink();
2149 break;
2150 }
2151
2152 case SCH_TEXTBOX_T:
2153 {
2154 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
2155 BOX2I bbox = textbox->GetBoundingBox();
2156
2157 bbox.SetOrigin( bbox.GetLeft() + textbox->GetMarginLeft(),
2158 bbox.GetTop() + textbox->GetMarginTop() );
2159 bbox.SetEnd( bbox.GetRight() - textbox->GetMarginRight(),
2160 bbox.GetBottom() - textbox->GetMarginBottom() );
2161
2162 if( convertTo == SCH_LABEL_T
2163 || convertTo == SCH_HIER_LABEL_T
2164 || convertTo == SCH_GLOBAL_LABEL_T )
2165 {
2166 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
2167 wxCHECK( text, 0 );
2168 int textSize = text->GetTextSize().y;
2169 bbox.Inflate( KiROUND( item->Schematic()->Settings().m_LabelSizeRatio * textSize ) );
2170 }
2171
2172 txt = textbox->GetText();
2173
2174 if( textbox->GetTextAngle().IsVertical() )
2175 {
2176 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2177 {
2178 spinStyle = SPIN_STYLE::SPIN::BOTTOM;
2179 position = VECTOR2I( bbox.Centre().x, bbox.GetOrigin().y );
2180 }
2181 else
2182 {
2183 spinStyle = SPIN_STYLE::SPIN::UP;
2184 position = VECTOR2I( bbox.Centre().x, bbox.GetEnd().y );
2185 }
2186 }
2187 else
2188 {
2189 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2190 {
2191 spinStyle = SPIN_STYLE::SPIN::LEFT;
2192 position = VECTOR2I( bbox.GetEnd().x, bbox.Centre().y );
2193 }
2194 else
2195 {
2196 spinStyle = SPIN_STYLE::SPIN::RIGHT;
2197 position = VECTOR2I( bbox.GetOrigin().x, bbox.Centre().y );
2198 }
2199 }
2200
2201 position = m_frame->GetNearestGridPosition( position );
2202 href = textbox->GetHyperlink();
2203 break;
2204 }
2205
2206 default:
2207 UNIMPLEMENTED_FOR( item->GetClass() );
2208 break;
2209 }
2210
2211 auto getValidNetname =
2212 []( const wxString& aText )
2213 {
2214 wxString local_txt = aText;
2215 local_txt.Replace( "\n", "_" );
2216 local_txt.Replace( "\r", "_" );
2217 local_txt.Replace( "\t", "_" );
2218
2219 // Bus groups can have spaces; bus vectors and signal names cannot
2220 if( !NET_SETTINGS::ParseBusGroup( aText, nullptr, nullptr ) )
2221 local_txt.Replace( " ", "_" );
2222
2223 // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
2224 local_txt = EscapeString( local_txt, CTX_NETNAME );
2225
2226 if( local_txt.IsEmpty() )
2227 return _( "<empty>" );
2228 else
2229 return local_txt;
2230 };
2231
2232 switch( convertTo )
2233 {
2234 case SCH_LABEL_T:
2235 {
2236 SCH_LABEL_BASE* new_label = new SCH_LABEL( position, getValidNetname( txt ) );
2237
2238 new_label->SetShape( shape );
2239 new_label->SetAttributes( *sourceText, false );
2240 new_label->SetSpinStyle( spinStyle );
2241 new_label->SetHyperlink( href );
2242
2243 if( item->Type() == SCH_GLOBAL_LABEL_T || item->Type() == SCH_HIER_LABEL_T )
2244 {
2245 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2246 new_label->MirrorVertically( position.y );
2247 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2248 new_label->MirrorVertically( position.y );
2249 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2250 new_label->MirrorHorizontally( position.x );
2251 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2252 new_label->MirrorHorizontally( position.x );
2253 }
2254
2255 newtext = new_label;
2256 break;
2257 }
2258
2259 case SCH_GLOBAL_LABEL_T:
2260 {
2261 SCH_LABEL_BASE* new_label = new SCH_GLOBALLABEL( position, getValidNetname( txt ) );
2262
2263 new_label->SetShape( shape );
2264 new_label->SetAttributes( *sourceText, false );
2265 new_label->SetSpinStyle( spinStyle );
2266 new_label->SetHyperlink( href );
2267
2268 if( item->Type() == SCH_LABEL_T )
2269 {
2270 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2271 new_label->MirrorVertically( position.y );
2272 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2273 new_label->MirrorVertically( position.y );
2274 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2275 new_label->MirrorHorizontally( position.x );
2276 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2277 new_label->MirrorHorizontally( position.x );
2278 }
2279
2280 newtext = new_label;
2281 break;
2282 }
2283
2284 case SCH_HIER_LABEL_T:
2285 {
2286 SCH_LABEL_BASE* new_label = new SCH_HIERLABEL( position, getValidNetname( txt ) );
2287
2288 new_label->SetShape( shape );
2289 new_label->SetAttributes( *sourceText, false );
2290 new_label->SetSpinStyle( spinStyle );
2291 new_label->SetHyperlink( href );
2292
2293 if( item->Type() == SCH_LABEL_T )
2294 {
2295 if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::UP )
2296 new_label->MirrorVertically( position.y );
2297 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::BOTTOM )
2298 new_label->MirrorVertically( position.y );
2299 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::LEFT )
2300 new_label->MirrorHorizontally( position.x );
2301 else if( static_cast<SCH_LABEL_BASE*>( item )->GetSpinStyle() == SPIN_STYLE::SPIN::RIGHT )
2302 new_label->MirrorHorizontally( position.x );
2303 }
2304
2305 newtext = new_label;
2306 break;
2307 }
2308
2310 {
2311 SCH_LABEL_BASE* new_label = new SCH_DIRECTIVE_LABEL( position );
2312
2313 // A SCH_DIRECTIVE_LABEL usually has at least one field containing the net class
2314 // name. If we're copying from a text object assume the text is the netclass
2315 // name. Otherwise, we'll just copy the fields which will either have a netclass
2316 // or not.
2317 if( !dynamic_cast<SCH_LABEL_BASE*>( item ) )
2318 {
2319 SCH_FIELD netclass( position, 0, new_label, wxT( "Netclass" ) );
2320 netclass.SetText( txt );
2321 netclass.SetVisible( true );
2322 new_label->GetFields().push_back( netclass );
2323 }
2324
2325 new_label->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
2326 new_label->SetAttributes( *sourceText, false );
2327 new_label->SetSpinStyle( spinStyle );
2328 new_label->SetHyperlink( href );
2329 newtext = new_label;
2330 break;
2331 }
2332
2333 case SCH_TEXT_T:
2334 {
2335 SCH_TEXT* new_text = new SCH_TEXT( position, txt );
2336
2337 new_text->SetAttributes( *sourceText, false );
2338 new_text->SetHyperlink( href );
2339 newtext = new_text;
2340 break;
2341 }
2342
2343 case SCH_TEXTBOX_T:
2344 {
2345 SCH_TEXTBOX* new_textbox = new SCH_TEXTBOX( LAYER_NOTES, 0, FILL_T::NO_FILL, txt );
2346 BOX2I bbox = item->GetBoundingBox();
2347
2348 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
2349 bbox.Inflate( -label->GetLabelBoxExpansion() );
2350
2351 new_textbox->SetAttributes( *sourceText, false );
2352
2353 bbox.SetOrigin( bbox.GetLeft() - new_textbox->GetMarginLeft(),
2354 bbox.GetTop() - new_textbox->GetMarginTop() );
2355 bbox.SetEnd( bbox.GetRight() + new_textbox->GetMarginRight(),
2356 bbox.GetBottom() + new_textbox->GetMarginBottom() );
2357
2358 VECTOR2I topLeft = bbox.GetPosition();
2359 VECTOR2I botRight = bbox.GetEnd();
2360
2361 // Add 1/20 of the margin at the end to reduce line-breaking changes.
2362 int slop = new_textbox->GetLegacyTextMargin() / 20;
2363
2364 if( sourceText->GetTextAngle() == ANGLE_VERTICAL )
2365 {
2366 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2367 botRight.y += slop;
2368 else
2369 topLeft.y -= slop;
2370 }
2371 else
2372 {
2373 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2374 topLeft.x -= slop;
2375 else
2376 botRight.x += slop;
2377 }
2378
2379 new_textbox->SetPosition( topLeft );
2380 new_textbox->SetEnd( botRight );
2381
2382 new_textbox->SetHyperlink( href );
2383 newtext = new_textbox;
2384 break;
2385 }
2386
2387 default:
2388 UNIMPLEMENTED_FOR( wxString::Format( "%d.", convertTo ) );
2389 break;
2390 }
2391
2392 wxCHECK2( newtext, continue );
2393
2394 // Copy the old text item settings to the new one. Justifications are not copied
2395 // because they are not used in labels. Justifications will be set to default value
2396 // in the new text item type.
2397 //
2398 newtext->SetFlags( item->GetEditFlags() );
2399
2400 EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( item );
2401 EDA_TEXT* new_eda_text = dynamic_cast<EDA_TEXT*>( newtext );
2402
2403 wxCHECK2( eda_text && new_eda_text, continue );
2404
2405 new_eda_text->SetFont( eda_text->GetFont() );
2406 new_eda_text->SetTextSize( eda_text->GetTextSize() );
2407 new_eda_text->SetTextThickness( eda_text->GetTextThickness() );
2408
2409 // Must be after SetTextSize()
2410 new_eda_text->SetBold( eda_text->IsBold() );
2411 new_eda_text->SetItalic( eda_text->IsItalic() );
2412
2413 newtext->AutoplaceFields( m_frame->GetScreen(), false );
2414
2415 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item );
2416 SCH_LABEL_BASE* new_label = dynamic_cast<SCH_LABEL_BASE*>( newtext );
2417
2418 if( label && new_label )
2419 {
2420 new_label->AddFields( label->GetFields() );
2421
2422 // A SCH_GLOBALLABEL has a specific field, that has no meaning for
2423 // other labels, and expected to be the first field in list.
2424 // It is the first field in list for this kind of label
2425 // So remove field named "Intersheetrefs" if exists for other labels
2426 int min_idx = new_label->Type() == SCH_GLOBAL_LABEL_T ? 1 : 0;
2427 std::vector<SCH_FIELD>& fields = new_label->GetFields();
2428
2429 for( int ii = fields.size()-1; ii >= min_idx; ii-- )
2430 {
2431 if( fields[ii].GetCanonicalName() == wxT( "Intersheetrefs" ) )
2432 fields.erase( fields.begin() + ii );
2433 }
2434 }
2435
2436 if( selected )
2438
2439 if( !item->IsNew() )
2440 {
2442 commit.Removed( item, m_frame->GetScreen() );
2443
2444 m_frame->AddToScreen( newtext, m_frame->GetScreen() );
2445 commit.Added( newtext, m_frame->GetScreen() );
2446 }
2447
2448 if( selected )
2450
2451 // Otherwise, pointer is owned by the undo stack
2452 if( item->IsNew() )
2453 delete item;
2454 }
2455 }
2456
2457 if( !commit.Empty() )
2458 commit.Push( _( "Change To" ) );
2459
2460 if( selection.IsHover() )
2462
2463 return 0;
2464}
2465
2466
2468{
2469 static std::vector<KICAD_T> justifiableItems = {
2471 SCH_TEXT_T,
2474 };
2475
2476 EE_SELECTION& selection = m_selectionTool->RequestSelection( justifiableItems );
2477
2478 if( selection.GetSize() == 0 )
2479 return 0;
2480
2481 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
2482 bool moving = item->IsMoving();
2483 SCH_COMMIT localCommit( m_toolMgr );
2484 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
2485
2486 if( !commit )
2487 commit = &localCommit;
2488
2489 auto setJustify =
2490 [&]( EDA_TEXT* aTextItem )
2491 {
2492 if( aEvent.Matches( ACTIONS::leftJustify.MakeEvent() ) )
2493 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
2494 else if( aEvent.Matches( ACTIONS::centerJustify.MakeEvent() ) )
2495 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
2496 else
2497 aTextItem->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2498 };
2499
2500 for( EDA_ITEM* edaItem : selection )
2501 {
2502 item = static_cast<SCH_ITEM*>( edaItem );
2503
2504 if( !moving )
2505 commit->Modify( item, m_frame->GetScreen() );
2506
2507 if( item->Type() == SCH_FIELD_T )
2508 {
2509 setJustify( static_cast<SCH_FIELD*>( item ) );
2510
2511 // Now that we're re-justifying a field, they're no longer autoplaced.
2512 static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
2513 }
2514 else if( item->Type() == SCH_TEXT_T )
2515 {
2516 setJustify( static_cast<SCH_TEXT*>( item ) );
2517 }
2518 else if( item->Type() == SCH_TEXTBOX_T )
2519 {
2520 setJustify( static_cast<SCH_TEXTBOX*>( item ) );
2521 }
2522 else if( item->Type() == SCH_LABEL_T )
2523 {
2524 SCH_LABEL* label = static_cast<SCH_LABEL*>( item );
2525
2526 if( label->GetTextAngle() == ANGLE_HORIZONTAL )
2527 setJustify( label );
2528 }
2529
2530 m_frame->UpdateItem( item, false, true );
2531 }
2532
2533 // Update R-Tree for modified items
2534 for( EDA_ITEM* selected : selection )
2535 updateItem( selected, true );
2536
2537 if( item->IsMoving() )
2538 {
2540 }
2541 else
2542 {
2543 EE_SELECTION selectionCopy = selection;
2544
2545 if( selection.IsHover() )
2547
2548 if( !localCommit.Empty() )
2549 {
2550 if( aEvent.Matches( ACTIONS::leftJustify.MakeEvent() ) )
2551 localCommit.Push( _( "Left Justify" ) );
2552 else if( aEvent.Matches( ACTIONS::centerJustify.MakeEvent() ) )
2553 localCommit.Push( _( "Center Justify" ) );
2554 else
2555 localCommit.Push( _( "Right Justify" ) );
2556 }
2557 }
2558
2559 return 0;
2560}
2561
2562
2564{
2565 bool isSlice = aEvent.Matches( EE_ACTIONS::slice.MakeEvent() );
2568 SCH_SCREEN* screen = m_frame->GetScreen();
2569 SCH_COMMIT commit( m_toolMgr );
2570 std::vector<SCH_LINE*> lines;
2571
2572 for( EDA_ITEM* item : selection )
2573 {
2574 if( item->Type() == SCH_LINE_T )
2575 {
2576 SCH_LINE* line = static_cast<SCH_LINE*>( item );
2577
2578 if( !line->IsEndPoint( cursorPos ) )
2579 lines.push_back( line );
2580 }
2581 }
2582
2584
2585 for( SCH_LINE* line : lines )
2586 {
2587 SCH_LINE* newLine;
2588
2589 // We let the user select the break point if they're on a single line
2590 if( lines.size() == 1 && line->HitTest( cursorPos ) )
2591 m_frame->BreakSegment( &commit, line, cursorPos, &newLine, screen );
2592 else
2593 m_frame->BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
2594
2595 // Make sure both endpoints are deselected
2596 newLine->ClearFlags();
2597
2599 line->SetFlags( ENDPOINT );
2600
2601 // If we're a break, we want to drag both wires.
2602 // Side note: the drag/move tool only checks whether the first item is
2603 // new to determine if it should append undo or not, someday this should
2604 // be cleaned up and explictly controlled but for now the newLine
2605 // selection addition must be after the existing line.
2606 if( !isSlice )
2607 {
2608 m_selectionTool->AddItemToSel( newLine );
2609 newLine->SetFlags( STARTPOINT );
2610 }
2611 }
2612
2613 if( !lines.empty() )
2614 {
2616
2617 if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::drag, &commit, isSlice ) )
2618 commit.Push( isSlice ? _( "Slice Wire" ) : _( "Break Wire" ) );
2619 else
2620 commit.Revert();
2621 }
2622
2623 return 0;
2624}
2625
2626
2628{
2630 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2631 SCH_COMMIT commit( m_toolMgr );
2632
2633 if( !sheet || !sheet->HasUndefinedPins() )
2634 return 0;
2635
2636 if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
2637 return 0;
2638
2639 commit.Modify( sheet, m_frame->GetScreen() );
2640
2641 sheet->CleanupSheet();
2642
2643 updateItem( sheet, true );
2644
2645 commit.Push( _( "Cleanup Sheet Pins" ) );
2646
2647 if( selection.IsHover() )
2649
2650 return 0;
2651}
2652
2653
2655{
2657
2658 if( selection.GetSize() > 1 )
2659 return 0;
2660
2661 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2662
2664
2665 SCH_SCREEN* screen;
2666
2667 if( sheet )
2668 {
2669 // When changing the page number of a selected sheet, the current screen owns the sheet.
2670 screen = m_frame->GetScreen();
2671
2672 instance.push_back( sheet );
2673 }
2674 else
2675 {
2676 SCH_SHEET_PATH prevInstance = instance;
2677
2678 // When change the page number in the screen, the previous screen owns the sheet.
2679 if( prevInstance.size() )
2680 {
2681 prevInstance.pop_back();
2682 screen = prevInstance.LastScreen();
2683 }
2684 else
2685 {
2686 // The root sheet and root screen are effectively the same thing.
2687 screen = m_frame->GetScreen();
2688 }
2689
2690 sheet = m_frame->GetCurrentSheet().Last();
2691 }
2692
2693 wxString msg;
2694 wxString sheetPath = instance.PathHumanReadable( false );
2695 wxString pageNumber = instance.GetPageNumber();
2696
2697 msg.Printf( _( "Enter page number for sheet path%s" ),
2698 ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
2699
2700 wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
2701
2702 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
2703
2704 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
2705 return 0;
2706
2707 m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
2708
2709 instance.SetPageNumber( dlg.GetValue() );
2710
2711 if( instance == m_frame->GetCurrentSheet() )
2712 {
2713 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
2715 }
2716
2717 m_frame->OnModify();
2718
2719 // Update the hierarchy navigator labels if needed
2720 if( pageNumber != dlg.GetValue() )
2722
2723 return 0;
2724}
2725
2726
2728{
2729 wxString aFileName = *aEvent.Parameter<wxString*>();
2730 return ( m_frame->AddSheetAndUpdateDisplay( aFileName ) ? 0 : 1 );
2731}
2732
2733
2735{
2737 SCH_COMMIT commit( m_toolMgr );
2738
2739 if( selection.Empty() )
2740 return 0;
2741
2742 for( EDA_ITEM* item : selection )
2743 {
2744 if( item->Type() == SCH_SYMBOL_T )
2745 {
2746 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2747
2748 commit.Modify( symbol, m_frame->GetScreen() );
2749
2750 if( aEvent.IsAction( &EE_ACTIONS::setDNP ) )
2751 symbol->SetDNP( true );
2752
2754 symbol->SetExcludedFromSim( true );
2755
2757 symbol->SetExcludedFromBOM( true );
2758
2760 symbol->SetExcludedFromBoard( true );
2761 }
2762 }
2763
2764 if( !commit.Empty() )
2765 commit.Push( _( "Set Attribute" ) );
2766
2767 return 0;
2768}
2769
2770
2772{
2774 SCH_COMMIT commit( m_toolMgr );
2775
2776 if( selection.Empty() )
2777 return 0;
2778
2779 for( EDA_ITEM* item : selection )
2780 {
2781 if( item->Type() == SCH_SYMBOL_T )
2782 {
2783 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2784
2785 commit.Modify( symbol, m_frame->GetScreen() );
2786
2787 if( aEvent.IsAction( &EE_ACTIONS::unsetDNP ) )
2788 symbol->SetDNP( false );
2789
2791 symbol->SetExcludedFromSim( false );
2792
2794 symbol->SetExcludedFromBOM( false );
2795
2797 symbol->SetExcludedFromBoard( false );
2798 }
2799 }
2800
2801 if( !commit.Empty() )
2802 commit.Push( _( "Clear Attribute" ) );
2803
2804 return 0;
2805}
2806
2807
2809{
2811 SCH_COMMIT commit( m_toolMgr );
2812
2813 if( selection.Empty() )
2814 return 0;
2815
2816 for( EDA_ITEM* item : selection )
2817 {
2818 if( item->Type() == SCH_SYMBOL_T )
2819 {
2820 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2821
2822 commit.Modify( symbol, m_frame->GetScreen() );
2823
2824 if( aEvent.IsAction( &EE_ACTIONS::toggleDNP ) )
2825 symbol->SetDNP( !symbol->GetDNP() );
2826
2828 symbol->SetExcludedFromSim( !symbol->GetExcludedFromSim() );
2829
2831 symbol->SetExcludedFromBOM( !symbol->GetExcludedFromBOM() );
2832
2834 symbol->SetExcludedFromBoard( !symbol->GetExcludedFromBoard() );
2835 }
2836 }
2837
2838 if( !commit.Empty() )
2839 commit.Push( _( "Toggle Attribute" ) );
2840
2841 return 0;
2842
2843}
2844
2845
2847{
2853 Go( &SCH_EDIT_TOOL::Swap, EE_ACTIONS::swap.MakeEvent() );
2856
2878
2881
2894
2898
2900}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
static TOOL_ACTION paste
Definition: actions.h:70
static TOOL_ACTION unselectAll
Definition: actions.h:73
static TOOL_ACTION copy
Definition: actions.h:69
static TOOL_ACTION pickerTool
Definition: actions.h:189
static TOOL_ACTION pasteSpecial
Definition: actions.h:71
static TOOL_ACTION rightJustify
Definition: actions.h:79
static TOOL_ACTION pageSettings
Definition: actions.h:56
static TOOL_ACTION duplicate
Definition: actions.h:74
static TOOL_ACTION doDelete
Definition: actions.h:75
static TOOL_ACTION deleteTool
Definition: actions.h:76
static TOOL_ACTION leftJustify
Definition: actions.h:77
static TOOL_ACTION cut
Definition: actions.h:68
static TOOL_ACTION refreshPreview
Definition: actions.h:137
static TOOL_ACTION selectAll
Definition: actions.h:72
static TOOL_ACTION centerJustify
Definition: actions.h:78
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 SetOrigin(const Vec &pos)
Definition: box2.h:227
const Vec & GetPosition() const
Definition: box2.h:201
const Vec & GetOrigin() const
Definition: box2.h:200
const Vec GetCenter() const
Definition: box2.h:220
coord_type GetTop() const
Definition: box2.h:219
const Vec GetEnd() const
Definition: box2.h:202
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
Vec Centre() const
Definition: box2.h:87
coord_type GetRight() const
Definition: box2.h:207
coord_type GetLeft() const
Definition: box2.h:218
coord_type GetBottom() const
Definition: box2.h:212
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:280
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()
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:180
bool IsVertical() const
Definition: eda_angle.h:185
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:88
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:242
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:243
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:132
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:126
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:128
bool IsSelected() const
Definition: eda_item.h:109
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:175
EDA_ITEM * GetParent() const
Definition: eda_item.h:102
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:130
virtual wxString GetClass() const =0
Return the class name.
bool IsMoving() const
Definition: eda_item.h:107
bool IsNew() const
Definition: eda_item.h:106
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:154
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:83
bool IsItalic() const
Definition: eda_text.h:144
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:374
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
virtual bool IsVisible() const
Definition: eda_text.h:151
KIFONT::FONT * GetFont() const
Definition: eda_text.h:211
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:292
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:276
wxString GetHyperlink() const
Definition: eda_text.h:362
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:164
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:245
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsBold() const
Definition: eda_text.h:148
void SetHyperlink(wxString aLink)
Definition: eda_text.h:363
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:167
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:205
int GetTextThickness() const
Definition: eda_text.h:126
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:358
VECTOR2I GetTextSize() const
Definition: eda_text.h:222
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:268
PANEL_ANNOTATE m_AnnotatePanel
AUTOPLACE_FIELDS m_AutoplaceFields
static TOOL_ACTION mirrorV
Definition: ee_actions.h:126
static TOOL_ACTION unsetDNP
Definition: ee_actions.h:196
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
static TOOL_ACTION properties
Definition: ee_actions.h:129
static TOOL_ACTION toggleExcludeFromSimulation
Definition: ee_actions.h:191
static TOOL_ACTION unsetExcludeFromSimulation
Definition: ee_actions.h:190
static TOOL_ACTION setExcludeFromBoard
Definition: ee_actions.h:192
static TOOL_ACTION move
Definition: ee_actions.h:121
static TOOL_ACTION clearHighlight
Definition: ee_actions.h:293
static TOOL_ACTION toGLabel
Definition: ee_actions.h:141
static TOOL_ACTION toggleExcludeFromBoard
Definition: ee_actions.h:194
static TOOL_ACTION setDNP
Definition: ee_actions.h:195
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:230
static TOOL_ACTION slice
Definition: ee_actions.h:145
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION drag
Definition: ee_actions.h:122
static TOOL_ACTION toText
Definition: ee_actions.h:142
static TOOL_ACTION placeClassLabel
Definition: ee_actions.h:88
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:136
static TOOL_ACTION toggleExcludeFromBOM
Definition: ee_actions.h:188
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:133
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:135
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:125
static TOOL_ACTION editValue
Definition: ee_actions.h:131
static TOOL_ACTION toLabel
Definition: ee_actions.h:138
static TOOL_ACTION toTextBox
Definition: ee_actions.h:143
static TOOL_ACTION breakWire
Definition: ee_actions.h:144
static TOOL_ACTION mirrorH
Definition: ee_actions.h:127
static TOOL_ACTION rotateCW
Definition: ee_actions.h:124
static TOOL_ACTION unsetExcludeFromBOM
Definition: ee_actions.h:187
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:173
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:89
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:60
static TOOL_ACTION ddAppendFile
Definition: ee_actions.h:299
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:90
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:164
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:159
static TOOL_ACTION editFootprint
Definition: ee_actions.h:132
static TOOL_ACTION enterSheet
Definition: ee_actions.h:219
static TOOL_ACTION editReference
Definition: ee_actions.h:130
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:158
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:97
static TOOL_ACTION setExcludeFromBOM
Definition: ee_actions.h:186
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:157
static TOOL_ACTION setExcludeFromSimulation
Definition: ee_actions.h:189
static TOOL_ACTION unsetExcludeFromBoard
Definition: ee_actions.h:193
static TOOL_ACTION toCLabel
Definition: ee_actions.h:139
static TOOL_ACTION placeLabel
Definition: ee_actions.h:87
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:123
static TOOL_ACTION toHLabel
Definition: ee_actions.h:140
static TOOL_ACTION editTextAndGraphics
Definition: ee_actions.h:231
static TOOL_ACTION toggleDNP
Definition: ee_actions.h:197
static TOOL_ACTION swap
Definition: ee_actions.h:128
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:134
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:160
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 SingleMultiFunctionPin
static SELECTION_CONDITION SingleSymbolOrPower
static SELECTION_CONDITION SingleMultiUnitSymbol
static SELECTION_CONDITION AllPins
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:1410
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:412
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
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:223
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:83
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:72
void SetSnapping(bool aSnap)
Definition: picker_tool.h:65
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:63
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:103
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 settings were stored in SCH_BASE_FRAME previously.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
SCH_SHEET & Root() const
Definition: schematic.h:105
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:41
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:405
virtual void Revert() override
Definition: sch_commit.cpp:483
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:193
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 *aClearAnnotationNewItems, bool *aUpdateHierarchyNavigator=nullptr)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:591
void FlipBodyStyle(SCH_SYMBOL *aSymbol)
Definition: picksymbol.cpp:126
void OnPageSettingsChange() override
Called when modifying the page settings.
bool AddSheetAndUpdateDisplay(const wxString aFullFileName)
Add a sheet file into the current sheet and updates display.
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet)
Verify that aSheet will not cause a recursion error in aCurrentSheet.
Definition: sheet.cpp:49
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 AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
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 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:1429
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:996
int GetId() const
Definition: sch_field.h:133
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1149
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1138
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:174
virtual bool IsConnectable() const
Definition: sch_item.h:457
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:155
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:139
int GetBodyStyle() const
Definition: sch_item.h:240
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
Definition: sch_item.h:351
virtual void Move(const VECTOR2I &aMoveVector)
Move the item by aMoveVector to a new position.
Definition: sch_item.h:343
int GetUnit() const
Definition: sch_item.h:237
void ClearFieldsAutoplaced()
Definition: sch_item.h:559
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_item.h:367
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:574
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:184
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:568
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:587
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:472
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:120
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:189
virtual void MirrorVertically(int aCenter)
Mirror item vertically about aCenter.
Definition: sch_item.h:359
void AddFields(const std::vector< SCH_FIELD > &aFields)
Definition: sch_label.h:209
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:524
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:373
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:173
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:172
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:543
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:196
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:338
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:40
void RotateEnd(const VECTOR2I &aCenter)
Definition: sch_line.cpp:432
void RotateStart(const VECTOR2I &aCenter)
Definition: sch_line.cpp:426
VECTOR2I GetEndPoint() const
Definition: sch_line.h:140
VECTOR2I GetStartPoint() const
Definition: sch_line.h:135
bool IsEndPoint(const VECTOR2I &aPoint) const
Definition: sch_line.h:89
const wxString & GetName() const
Definition: sch_pin.cpp:351
std::map< wxString, ALT > & GetAlternates()
Definition: sch_pin.h:121
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:704
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:486
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
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:389
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:115
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:299
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
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
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:699
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:559
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:383
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:445
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:667
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:688
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:845
Schematic symbol object.
Definition: sch_symbol.h:108
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:827
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:910
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:232
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:197
int GetOrientation() const
Get the display symbol orientation.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:216
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:75
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:243
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:255
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:120
const std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:222
VECTOR2I GetReferencePoint() const
Definition: selection.cpp:170
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:93
bool IsHover() const
Definition: selection.h:83
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:99
EDA_ITEM * Front() const
Definition: selection.h:208
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:213
bool OnlyContains(std::vector< KICAD_T > aList) const
Checks if all items in the selection have a type in aList.
Definition: selection.cpp:212
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
bool HasReferencePoint() const
Definition: selection.h:247
size_t CountType(KICAD_T aType) const
Definition: selection.cpp:156
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
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:216
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool 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:145
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:230
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:192
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
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:432
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:431
#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
@ ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL
Definition: eeschema_id.h:92
@ ID_POPUP_SCH_PIN_TRICKS_WIRE
Definition: eeschema_id.h:90
@ ID_POPUP_SCH_ALT_PIN_FUNCTION
Definition: eeschema_id.h:96
@ ID_POPUP_SCH_SELECT_UNIT1
Definition: eeschema_id.h:83
@ ID_POPUP_SCH_SELECT_UNIT
Definition: eeschema_id.h:82
@ ID_POPUP_SCH_PIN_TRICKS_NET_LABEL
Definition: eeschema_id.h:91
@ ID_POPUP_SCH_PIN_TRICKS_NO_CONNECT
Definition: eeschema_id.h:89
@ ID_POPUP_SCH_SELECT_UNIT_END
Definition: eeschema_id.h:86
@ ID_POPUP_SCH_ALT_PIN_FUNCTION_END
Definition: eeschema_id.h:97
@ ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL
Definition: eeschema_id.h:93
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ LAYER_NOTES
Definition: layer_ids.h:371
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:396
#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:1059
see class PGM_BASE
static std::vector< KICAD_T > deletableItems
const std::vector< KICAD_T > swappableItems
LABEL_FLAG_SHAPE
Definition: sch_label.h:93
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:89
@ SYM_MIRROR_X
Definition: sch_symbol.h:88
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_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
#define TO_VJUSTIFY(x)
#define TO_HJUSTIFY(x)
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
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:118
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588