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