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-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <kiway.h>
26#include <tool/picker_tool.h>
27#include <tools/sch_edit_tool.h>
30#include <tools/sch_move_tool.h>
32#include <ee_actions.h>
33#include <confirm.h>
34#include <string_utils.h>
35#include <sch_item.h>
36#include <sch_symbol.h>
37#include <sch_shape.h>
38#include <sch_sheet.h>
39#include <sch_sheet_pin.h>
40#include <sch_text.h>
41#include <sch_textbox.h>
42#include <sch_bitmap.h>
43#include <sch_view.h>
44#include <sch_line.h>
45#include <sch_bus_entry.h>
46#include <sch_junction.h>
47#include <sch_edit_frame.h>
48#include <schematic.h>
49#include <sch_commit.h>
51#include <eeschema_id.h>
62#include <dialogs/dialog_text_properties.h>
63#include <pgm_base.h>
66#include <core/kicad_algo.h>
67#include <wx/textdlg.h>
69
71{
72public:
74 ACTION_MENU( true )
75 {
76 SetIcon( BITMAPS::component_select_unit );
77 SetTitle( _( "Symbol Unit" ) );
78 }
79
80protected:
81 ACTION_MENU* create() const override
82 {
83 return new SYMBOL_UNIT_MENU();
84 }
85
86private:
87 void update() override
88 {
90 EE_SELECTION& selection = selTool->GetSelection();
91 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
92
93 Clear();
94
95 if( !symbol )
96 {
97 Append( ID_POPUP_SCH_SELECT_UNIT, _( "no symbol selected" ), wxEmptyString );
98 Enable( ID_POPUP_SCH_SELECT_UNIT, false );
99 return;
100 }
101
102 int unit = symbol->GetUnit();
103
104 if( !symbol->GetLibSymbolRef() || symbol->GetLibSymbolRef()->GetUnitCount() < 2 )
105 {
106 Append( ID_POPUP_SCH_SELECT_UNIT, _( "symbol is not multi-unit" ), wxEmptyString );
107 Enable( ID_POPUP_SCH_SELECT_UNIT, false );
108 return;
109 }
110
111 for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
112 {
113 wxString num_unit;
114 num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
115
116 wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
117 wxITEM_CHECK );
118
119 if( unit == ii + 1 )
120 item->Check( true );
121
122 // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_END
123 // See eeschema_id to modify this value.
125 break; // We have used all IDs for these submenus
126 }
127 }
128};
129
130
132{
133public:
135 ACTION_MENU( true )
136 {
137 SetIcon( BITMAPS::component_select_unit );
138 SetTitle( _( "Pin Function" ) );
139 }
140
141protected:
142 ACTION_MENU* create() const override
143 {
144 return new ALT_PIN_FUNCTION_MENU();
145 }
146
147private:
148 void update() override
149 {
151 EE_SELECTION& selection = selTool->GetSelection();
152 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
153
154 Clear();
155
156 if( !pin )
157 {
158 Append( ID_POPUP_SCH_SELECT_UNIT, _( "no pin selected" ), wxEmptyString );
159 Enable( ID_POPUP_SCH_SELECT_UNIT, false );
160 return;
161 }
162
163 if( !pin->GetLibPin() || pin->GetLibPin()->GetAlternates().empty() )
164 {
165 Append( ID_POPUP_SCH_SELECT_UNIT, _( "no alternate pin functions defined" ), wxEmptyString );
166 Enable( ID_POPUP_SCH_SELECT_UNIT, false );
167 return;
168 }
169
170 wxMenuItem* item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION, pin->GetName(), wxEmptyString,
171 wxITEM_CHECK );
172
173 if( pin->GetAlt().IsEmpty() )
174 item->Check( true );
175
176 int ii = 1;
177
178 for( const auto& [ name, definition ] : pin->GetLibPin()->GetAlternates() )
179 {
180 item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION + ii, name, wxEmptyString, wxITEM_CHECK );
181
182 if( name == pin->GetAlt() )
183 item->Check( true );
184
185 // The ID max for these submenus is ID_POPUP_SCH_ALT_PIN_FUNCTION_END
186 // See eeschema_id to modify this value.
188 break; // We have used all IDs for these submenus
189 }
190 }
191};
192
193
195{
196public:
198 {
199 SetIcon( BITMAPS::pin );
200 SetTitle( _( "Pin Helpers" ) );
201 }
202
203protected:
204 ACTION_MENU* create() const override { return new PIN_TRICKS_MENU(); }
205
206private:
207 void update() override
208 {
210 EE_SELECTION& selection = selTool->GetSelection();
211 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
212
213 Clear();
214
215 if( !pin )
216 return;
217
218 Add( wxS( "Wire" ), ID_POPUP_SCH_PIN_TRICKS_WIRE, BITMAPS::add_line );
219 Add( wxS( "No Connect" ), ID_POPUP_SCH_PIN_TRICKS_NO_CONNECT, BITMAPS::noconn );
220 Add( wxS( "Net Label" ), ID_POPUP_SCH_PIN_TRICKS_NET_LABEL, BITMAPS::add_label );
221 Add( wxS( "Hierarchical Label" ), ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL,
222 BITMAPS::add_hierarchical_label );
223 Add( wxS( "Global Label" ), ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL, BITMAPS::add_glabel );
224 }
225};
226
227
229 EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
230{
231 m_pickerItem = nullptr;
232}
233
234
236
238{
240
243
244 wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
245
246 auto hasElements =
247 [this]( const SELECTION& aSel )
248 {
249 return !m_frame->GetScreen()->Items().empty();
250 };
251
252 auto sheetHasUndefinedPins =
253 []( const SELECTION& aSel )
254 {
255 if( aSel.Size() == 1 && aSel.Front()->Type() == SCH_SHEET_T )
256 return static_cast<SCH_SHEET*>( aSel.Front() )->HasUndefinedPins();
257
258 return false;
259 };
260
261 auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
262
263 auto haveHighlight =
264 [&]( const SELECTION& sel )
265 {
266 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
267
268 return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
269 };
270
271 auto anyTextTool =
272 [this]( const SELECTION& aSel )
273 {
279 };
280
281 auto duplicateCondition =
282 []( const SELECTION& aSel )
283 {
285 return false;
286
287 return true;
288 };
289
290 auto orientCondition =
291 []( const SELECTION& aSel )
292 {
294 return false;
295
297 };
298
299 auto propertiesCondition =
300 [&]( const SELECTION& aSel )
301 {
302 if( aSel.GetSize() == 0 )
303 {
305 {
308
309 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
310 return true;
311 }
312
313 return false;
314 }
315
316 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
317 const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
318
319 if( !firstItem || !eeSelection )
320 return false;
321
322 switch( firstItem->Type() )
323 {
324 case SCH_SYMBOL_T:
325 case SCH_SHEET_T:
326 case SCH_SHEET_PIN_T:
327 case SCH_TEXT_T:
328 case SCH_TEXTBOX_T:
329 case SCH_LABEL_T:
331 case SCH_HIER_LABEL_T:
333 case SCH_FIELD_T:
334 case SCH_SHAPE_T:
335 case SCH_BITMAP_T:
336 return aSel.GetSize() == 1;
337
338 case SCH_LINE_T:
340 case SCH_JUNCTION_T:
341 if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
342 [&]( const EDA_ITEM* item )
343 {
344 return item->Type() == SCH_LINE_T
345 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
346 } ) )
347 {
348 return true;
349 }
350 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
351 [&]( const EDA_ITEM* item )
352 {
353 return item->Type() == SCH_JUNCTION_T;
354 } ) )
355 {
356 return true;
357 }
358 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
359 [&]( const EDA_ITEM* item )
360 {
361 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
362
363 wxCHECK( schItem, false );
364
365 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
366 || item->Type() == SCH_JUNCTION_T;
367 } ) )
368 {
369 return true;
370 }
371
372 return false;
373
374 default:
375 return false;
376 }
377 };
378
379 auto autoplaceCondition =
380 []( const SELECTION& aSel )
381 {
382 for( const EDA_ITEM* item : aSel )
383 {
384 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
385 return true;
386 }
387
388 return false;
389 };
390
391 // allTextTypes does not include SCH_SHEET_PIN_T because one cannot convert other
392 // types to/from this type, living only in a SHEET
393 static std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
399
400 auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
401
402 auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_DIRECTIVE_LABEL_T,
406 SCH_TEXTBOX_T } ) )
407 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
408
409 auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
413 SCH_TEXTBOX_T } ) )
414 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
415
416 auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
420 SCH_TEXTBOX_T } ) )
421 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
422
423 auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
427 SCH_TEXTBOX_T } ) )
428 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
429
430 auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
434 SCH_TEXTBOX_T } ) )
435 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
436
437 auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
441 SCH_TEXT_T } ) )
442 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
443
444 auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_BUS_WIRE_ENTRY_T,
446
447 auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
448
449 //
450 // Add edit actions to the move tool menu
451 //
452 if( moveTool )
453 {
454 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
455
456 moveMenu.AddSeparator();
457
458 CONDITIONAL_MENU* transformMoveSubMenu = new CONDITIONAL_MENU( moveTool );
459 transformMoveSubMenu->SetTitle( _( "Transform Selection" ) );
460 moveMenu.AddMenu( transformMoveSubMenu, orientCondition, 200 );
461
462 transformMoveSubMenu->AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
463 transformMoveSubMenu->AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
464 transformMoveSubMenu->AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
465 transformMoveSubMenu->AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
466
467 {
468 CONDITIONAL_MENU *attribMoveSubMenu = new CONDITIONAL_MENU( moveTool );
469 attribMoveSubMenu->SetTitle( _( "Attributes" ) );
470 moveMenu.AddMenu( attribMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ), 200 );
471
472 {
473 CONDITIONAL_MENU *attribSimMoveSubMenu = new CONDITIONAL_MENU( moveTool );
474 attribSimMoveSubMenu->SetTitle( _( "Simulation" ) );
475 attribMoveSubMenu->AddMenu( attribSimMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
476 attribSimMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromSimulation,
478 attribSimMoveSubMenu->AddItem( EE_ACTIONS::unsetExcludeFromSimulation,
482 }
483
484 {
485 CONDITIONAL_MENU *attribBOMMoveSubMenu = new CONDITIONAL_MENU( moveTool );
486 attribBOMMoveSubMenu->SetTitle( _( "Bill of Materials" ) );
487 attribMoveSubMenu->AddMenu( attribBOMMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
488 attribBOMMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBOM, E_C::ShowAlways );
491 }
492
493 {
494 CONDITIONAL_MENU *attribBoardMoveSubMenu = new CONDITIONAL_MENU( moveTool );
495 attribBoardMoveSubMenu->SetTitle( _( "Exclude from board" ) );
496 attribMoveSubMenu->AddMenu( attribBoardMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
497 attribBoardMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBoard,
499 attribBoardMoveSubMenu->AddItem( EE_ACTIONS::unsetExcludeFromBoard,
501 attribBoardMoveSubMenu->AddItem( EE_ACTIONS::toggleExcludeFromBoard,
503 }
504
505 {
506 CONDITIONAL_MENU *attribDNPMoveSubMenu = new CONDITIONAL_MENU( moveTool );
507 attribDNPMoveSubMenu->SetTitle( _( "Do not populate" ) );
508 attribMoveSubMenu->AddMenu( attribDNPMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
509 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::setDNP, E_C::ShowAlways );
510 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::unsetDNP, E_C::ShowAlways );
511 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::toggleDNP, E_C::ShowAlways );
512 }
513 }
515
516 moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
517
518 CONDITIONAL_MENU* editMoveItemSubMenu = new CONDITIONAL_MENU(moveTool);
519 editMoveItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
520 editMoveItemSubMenu->SetIcon( BITMAPS::right );
521 moveMenu.AddMenu( editMoveItemSubMenu, E_C::SingleSymbol );
522
523 editMoveItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol );
524 editMoveItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol );
525 editMoveItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol );
526
527 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
528 symUnitMenu->SetTool( this );
529 m_menu.RegisterSubMenu( symUnitMenu );
530 moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
531
532 moveMenu.AddSeparator();
536 moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
537 }
538
539 //
540 // Add editing actions to the drawing tool menu
541 //
542 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
543
544 drawMenu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
545 drawMenu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
546
547 drawMenu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
548 drawMenu.AddSeparator( sheetSelection && EE_CONDITIONS::Idle, 1 );
549
550 CONDITIONAL_MENU* transformDrawSubMenu = new CONDITIONAL_MENU( drawingTools );
551 transformDrawSubMenu->SetTitle( _( "Transform Selection" ) );
552 drawMenu.AddMenu( transformDrawSubMenu, orientCondition, 200 );
553
554 transformDrawSubMenu->AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
555 transformDrawSubMenu->AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
556 transformDrawSubMenu->AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
557 transformDrawSubMenu->AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
558
559 {
560 CONDITIONAL_MENU *attribMoveSubMenu = new CONDITIONAL_MENU( moveTool );
561 attribMoveSubMenu->SetTitle( _( "Attributes" ) );
562 drawMenu.AddMenu( attribMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ), 200 );
563
564 {
565 CONDITIONAL_MENU *attribSimMoveSubMenu = new CONDITIONAL_MENU( moveTool );
566 attribSimMoveSubMenu->SetTitle( _( "Simulation" ) );
567 attribMoveSubMenu->AddMenu( attribSimMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
569 attribSimMoveSubMenu->AddItem( EE_ACTIONS::unsetExcludeFromSimulation,
573 }
574
575 {
576 CONDITIONAL_MENU *attribBOMMoveSubMenu = new CONDITIONAL_MENU( moveTool );
577 attribBOMMoveSubMenu->SetTitle( _( "Bill of Materials" ) );
578 attribMoveSubMenu->AddMenu( attribBOMMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
579 attribBOMMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBOM, E_C::ShowAlways );
582 }
583
584 {
585 CONDITIONAL_MENU *attribBoardMoveSubMenu = new CONDITIONAL_MENU( moveTool );
586 attribBoardMoveSubMenu->SetTitle( _( "Exclude from board" ) );
587 attribMoveSubMenu->AddMenu( attribBoardMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
588 attribBoardMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBoard, E_C::ShowAlways );
591 }
592
593 {
594 CONDITIONAL_MENU *attribDNPMoveSubMenu = new CONDITIONAL_MENU( moveTool );
595 attribDNPMoveSubMenu->SetTitle( _( "Do not populate" ) );
596 attribMoveSubMenu->AddMenu( attribDNPMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
597 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::setDNP, E_C::ShowAlways );
598 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::unsetDNP, E_C::ShowAlways );
599 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::toggleDNP, E_C::ShowAlways );
600 }
601 }
602
603 drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
604
605 CONDITIONAL_MENU* editDrawItemSubMenu = new CONDITIONAL_MENU( drawingTools );
606 editDrawItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
607 editDrawItemSubMenu->SetIcon( BITMAPS::right );
608 drawMenu.AddMenu( editDrawItemSubMenu, E_C::SingleSymbol, 200 );
609
610 editDrawItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
611 editDrawItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
612 editDrawItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
613
614
615 drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
616
617 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
618 symUnitMenu2->SetTool( drawingTools );
619 drawingTools->GetToolMenu().RegisterSubMenu( symUnitMenu2 );
620 drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
621
623
624 drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
625 drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
626 drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
627 drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
628 drawMenu.AddItem( EE_ACTIONS::toTextBox, anyTextTool && E_C::Idle, 200 );
629
630 //
631 // Add editing actions to the selection tool menu
632 //
634
635 CONDITIONAL_MENU* transformSelSubMenu = new CONDITIONAL_MENU( m_selectionTool );
636 transformSelSubMenu->SetTitle( _( "Transform Selection" ) );
637 selToolMenu.AddMenu( transformSelSubMenu, orientCondition, 200 );
638
639 transformSelSubMenu->AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
640 transformSelSubMenu->AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
641 transformSelSubMenu->AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
642 transformSelSubMenu->AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
643
644 {
645 CONDITIONAL_MENU *attribMoveSubMenu = new CONDITIONAL_MENU( moveTool );
646 attribMoveSubMenu->SetTitle( _( "Attributes" ) );
647 selToolMenu.AddMenu( attribMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ), 200 );
648
649 {
650 CONDITIONAL_MENU *attribSimMoveSubMenu = new CONDITIONAL_MENU( moveTool );
651 attribSimMoveSubMenu->SetTitle( _( "Simulation" ) );
652 attribMoveSubMenu->AddMenu( attribSimMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
654 attribSimMoveSubMenu->AddItem( EE_ACTIONS::unsetExcludeFromSimulation,
658 }
659
660 {
661 CONDITIONAL_MENU *attribBOMMoveSubMenu = new CONDITIONAL_MENU( moveTool );
662 attribBOMMoveSubMenu->SetTitle( _( "Bill of Materials" ) );
663 attribMoveSubMenu->AddMenu( attribBOMMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
664 attribBOMMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBOM, E_C::ShowAlways );
667 }
668
669 {
670 CONDITIONAL_MENU *attribBoardMoveSubMenu = new CONDITIONAL_MENU( moveTool );
671 attribBoardMoveSubMenu->SetTitle( _( "Exclude from board" ) );
672 attribMoveSubMenu->AddMenu( attribBoardMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
673 attribBoardMoveSubMenu->AddItem( EE_ACTIONS::setExcludeFromBoard, E_C::ShowAlways );
676 }
677
678 {
679 CONDITIONAL_MENU *attribDNPMoveSubMenu = new CONDITIONAL_MENU( moveTool );
680 attribDNPMoveSubMenu->SetTitle( _( "Do not populate" ) );
681 attribMoveSubMenu->AddMenu( attribDNPMoveSubMenu, E_C::HasType( SCH_SYMBOL_T ) );
682 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::setDNP, E_C::ShowAlways );
683 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::unsetDNP, E_C::ShowAlways );
684 attribDNPMoveSubMenu->AddItem( EE_ACTIONS::toggleDNP, E_C::ShowAlways );
685 }
686 }
687
689 selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
690
691 CONDITIONAL_MENU* editSelItemSubMenu = new CONDITIONAL_MENU( m_selectionTool );
692 editSelItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
693 editSelItemSubMenu->SetIcon( BITMAPS::right );
694 selToolMenu.AddMenu( editSelItemSubMenu, E_C::SingleSymbol, 200 );
695
696 editSelItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
697 editSelItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
698 editSelItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
699
700 selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
701
702 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
703 symUnitMenu3->SetTool( m_selectionTool );
705 selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
706
707 std::shared_ptr<ALT_PIN_FUNCTION_MENU> altPinMenu = std::make_shared<ALT_PIN_FUNCTION_MENU>();
708 altPinMenu->SetTool( m_selectionTool );
710 selToolMenu.AddMenu( altPinMenu.get(), E_C::SingleMultiFunctionPin, 1 );
711
712 std::shared_ptr<PIN_TRICKS_MENU> pinTricksMenu = std::make_shared<PIN_TRICKS_MENU>();
713 pinTricksMenu->SetTool( m_selectionTool );
714 m_selectionTool->GetToolMenu().RegisterSubMenu( pinTricksMenu );
715 selToolMenu.AddMenu( pinTricksMenu.get(), E_C::AllPins, 1 );
716
722
723 CONDITIONAL_MENU* convertToSubMenu = new CONDITIONAL_MENU( m_selectionTool );
724 convertToSubMenu->SetTitle( _( "Change To" ) );
725 convertToSubMenu->SetIcon( BITMAPS::right );
726 selToolMenu.AddMenu( convertToSubMenu, toChangeCondition, 200 );
727
728 convertToSubMenu->AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
729 convertToSubMenu->AddItem( EE_ACTIONS::toCLabel, toCLabelCondition, 200 );
730 convertToSubMenu->AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
731 convertToSubMenu->AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
732 convertToSubMenu->AddItem( EE_ACTIONS::toText, toTextCondition, 200 );
733 convertToSubMenu->AddItem( EE_ACTIONS::toTextBox, toTextBoxCondition, 200 );
734
735 selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
736
737 selToolMenu.AddSeparator( 300 );
738 selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
739 selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
740 selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
741 selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
742 selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
743 selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
744
745 selToolMenu.AddSeparator( 400 );
746 selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
747 selToolMenu.AddItem( ACTIONS::unselectAll, hasElements, 400 );
748
749 return true;
750}
751
752
753const std::vector<KICAD_T> SCH_EDIT_TOOL::RotatableItems = {
771};
772
773
775{
776 bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
778
779 if( selection.GetSize() == 0 )
780 return 0;
781
782 SCH_ITEM* head = nullptr;
783 int principalItemCount = 0; // User-selected items (as opposed to connected wires)
784 VECTOR2I rotPoint;
785 bool moving = false;
786 SCH_COMMIT localCommit( m_toolMgr );
787 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
788
789 if( !commit )
790 commit = &localCommit;
791
792 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
793 {
794 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
795
796 if( item->HasFlag( SELECTED_BY_DRAG ) )
797 continue;
798
799 principalItemCount++;
800
801 if( !head )
802 head = item;
803 }
804
805 if( head && head->IsMoving() )
806 moving = true;
807
808 if( principalItemCount == 1 )
809 {
810 if( moving && selection.HasReferencePoint() )
811 rotPoint = selection.GetReferencePoint();
812 else if( head->IsConnectable() )
813 rotPoint = head->GetPosition();
814 else
816
817 if( !moving )
818 commit->Modify( head, m_frame->GetScreen() );
819
820 switch( head->Type() )
821 {
822 case SCH_SYMBOL_T:
823 {
824 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
825
826 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
827 symbol->Rotate( rotPoint );
828
831
832 break;
833 }
834
835 case SCH_TEXT_T:
836 case SCH_LABEL_T:
838 case SCH_HIER_LABEL_T:
840 {
841 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
842 textItem->Rotate90( clockwise );
843 break;
844 }
845
846 case SCH_SHEET_PIN_T:
847 {
848 // Rotate pin within parent sheet
849 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
850 SCH_SHEET* sheet = pin->GetParent();
851
852 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
853 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
854
855 break;
856 }
857
858 case SCH_LINE_T:
859 {
860 SCH_LINE* line = static_cast<SCH_LINE*>( head );
861
862 // Equal checks for both and neither. We need this because on undo
863 // the item will have both flags cleared, but will be selected, so it is possible
864 // for the user to get a selected line with neither endpoint selected. We
865 // set flags to make sure Rotate() works when we call it.
866 if( line->HasFlag( STARTPOINT ) == line->HasFlag( ENDPOINT ) )
867 {
868 line->SetFlags( STARTPOINT | ENDPOINT );
869
870 // When we allow off grid items, the rotPoint should be set to the midpoint
871 // of the line to allow rotation around the center, and the next if
872 // should become an else-if
873 }
874
875 if( line->HasFlag( STARTPOINT ) )
876 rotPoint = line->GetEndPoint();
877 else if( line->HasFlag( ENDPOINT ) )
878 rotPoint = line->GetStartPoint();
879 }
880
882 case SCH_JUNCTION_T:
885 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
886 head->Rotate( rotPoint );
887
888 break;
889
890 case SCH_FIELD_T:
891 {
892 SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
893
894 if( field->GetTextAngle().IsHorizontal() )
896 else
898
899 // Now that we're moving a field, they're no longer autoplaced.
900 static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
901
902 break;
903 }
904
905 case SCH_SHAPE_T:
906 case SCH_TEXTBOX_T:
907 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
908 head->Rotate( rotPoint );
909
910 break;
911
912 case SCH_BITMAP_T:
913 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
914 head->Rotate( rotPoint );
915
916 // The bitmap is cached in Opengl: clear the cache to redraw
918 break;
919
920 case SCH_SHEET_T:
921 {
922 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
924
925 // Rotate the sheet on itself. Sheets do not have an anchor point.
926 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
927 sheet->Rotate( rotPoint );
928
929 break;
930 }
931
932 default:
933 UNIMPLEMENTED_FOR( head->GetClass() );
934 }
935
936 m_frame->UpdateItem( head, false, true );
937 }
938 else
939 {
940 if( moving && selection.HasReferencePoint() )
941 rotPoint = selection.GetReferencePoint();
942 else
943 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
944 }
945
946 for( EDA_ITEM* edaItem : selection )
947 {
948 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
949
950 // We've already rotated the user selected item if there was only one. We're just
951 // here to rotate the ends of wires that were attached to it.
952 if( principalItemCount == 1 && !item->HasFlag( SELECTED_BY_DRAG ) )
953 continue;
954
955 if( !moving )
956 commit->Modify( item, m_frame->GetScreen() );
957
958 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
959 {
960 if( item->Type() == SCH_LINE_T )
961 {
962 SCH_LINE* line = (SCH_LINE*) item;
963
964 // If we are rotating more than one item, we do not have start/end
965 // points separately selected
966 if( item->HasFlag( STARTPOINT ) )
967 line->RotateStart( rotPoint );
968
969 if( item->HasFlag( ENDPOINT ) )
970 line->RotateEnd( rotPoint );
971 }
972 else if( item->Type() == SCH_SHEET_PIN_T )
973 {
974 if( item->GetParent()->IsSelected() )
975 {
976 // parent will rotate us
977 }
978 else
979 {
980 // rotate within parent
981 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
982 SCH_SHEET* sheet = pin->GetParent();
983
984 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
985 }
986 }
987 else if( item->Type() == SCH_FIELD_T )
988 {
989 if( item->GetParent()->IsSelected() )
990 {
991 // parent will rotate us
992 }
993 else
994 {
995 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
996
997 field->Rotate( rotPoint );
998
999 if( field->GetTextAngle().IsHorizontal() )
1000 field->SetTextAngle( ANGLE_VERTICAL );
1001 else
1003
1004 // Now that we're moving a field, they're no longer autoplaced.
1005 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1006 }
1007 }
1008 else
1009 {
1010 item->Rotate( rotPoint );
1011 }
1012 }
1013
1014 m_frame->UpdateItem( item, false, true );
1015 updateItem( item, true );
1016 }
1017
1018 if( moving )
1019 {
1021 }
1022 else
1023 {
1024 EE_SELECTION selectionCopy = selection;
1025
1026 if( selection.IsHover() )
1028
1030 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
1031 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
1032
1033 m_frame->SchematicCleanUp( commit );
1034
1035 if( !localCommit.Empty() )
1036 localCommit.Push( _( "Rotate" ) );
1037 }
1038
1039 return 0;
1040}
1041
1042
1044{
1046
1047 if( selection.GetSize() == 0 )
1048 return 0;
1049
1050 bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
1051 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
1052 bool connections = false;
1053 bool moving = item->IsMoving();
1054 SCH_COMMIT localCommit( m_toolMgr );
1055 SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
1056
1057 if( !commit )
1058 commit = &localCommit;
1059
1060 if( selection.GetSize() == 1 )
1061 {
1062 if( !moving )
1063 commit->Modify( item, m_frame->GetScreen() );
1064
1065 switch( item->Type() )
1066 {
1067 case SCH_SYMBOL_T:
1068 {
1069 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1070
1071 if( vertical )
1072 symbol->SetOrientation( SYM_MIRROR_X );
1073 else
1074 symbol->SetOrientation( SYM_MIRROR_Y );
1075
1076 symbol->ClearFieldsAutoplaced();
1077 break;
1078 }
1079
1080 case SCH_TEXT_T:
1081 case SCH_LABEL_T:
1082 case SCH_GLOBAL_LABEL_T:
1083 case SCH_HIER_LABEL_T:
1085 {
1086 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
1087 textItem->MirrorSpinStyle( !vertical );
1088 break;
1089 }
1090
1091 case SCH_SHEET_PIN_T:
1092 {
1093 // mirror within parent sheet
1094 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1095 SCH_SHEET* sheet = pin->GetParent();
1096
1097 if( vertical )
1098 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
1099 else
1100 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
1101
1102 break;
1103 }
1104
1105 case SCH_FIELD_T:
1106 {
1107 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1108
1109 if( vertical )
1110 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
1111 else
1112 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
1113
1114 // Now that we're re-justifying a field, they're no longer autoplaced.
1115 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1116
1117 break;
1118 }
1119
1120 case SCH_BITMAP_T:
1121 if( vertical )
1122 item->MirrorVertically( item->GetPosition().y );
1123 else
1124 item->MirrorHorizontally( item->GetPosition().x );
1125
1126 // The bitmap is cached in Opengl: clear the cache to redraw
1128 break;
1129
1130 case SCH_SHEET_T:
1131 {
1132 // Mirror the sheet on itself. Sheets do not have a anchor point.
1134
1135 if( vertical )
1136 item->MirrorVertically( mirrorPoint.y );
1137 else
1138 item->MirrorHorizontally( mirrorPoint.x );
1139
1140 break;
1141 }
1142
1143 default:
1144 if( vertical )
1145 item->MirrorVertically( item->GetPosition().y );
1146 else
1147 item->MirrorHorizontally( item->GetPosition().x );
1148
1149 break;
1150 }
1151
1152 connections = item->IsConnectable();
1153 m_frame->UpdateItem( item, false, true );
1154 }
1155 else if( selection.GetSize() > 1 )
1156 {
1157 VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
1158
1159 for( EDA_ITEM* edaItem : selection )
1160 {
1161 item = static_cast<SCH_ITEM*>( edaItem );
1162
1163 if( !moving )
1164 commit->Modify( item, m_frame->GetScreen() );
1165
1166 if( item->Type() == SCH_SHEET_PIN_T )
1167 {
1168 if( item->GetParent()->IsSelected() )
1169 {
1170 // parent will mirror us
1171 }
1172 else
1173 {
1174 // mirror within parent sheet
1175 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1176 SCH_SHEET* sheet = pin->GetParent();
1177
1178 if( vertical )
1179 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
1180 else
1181 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
1182 }
1183 }
1184 else if( item->Type() == SCH_FIELD_T )
1185 {
1186 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1187
1188 if( vertical )
1189 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
1190 else
1191 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
1192
1193 // Now that we're re-justifying a field, they're no longer autoplaced.
1194 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
1195 }
1196 else
1197 {
1198 if( vertical )
1199 item->MirrorVertically( mirrorPoint.y );
1200 else
1201 item->MirrorHorizontally( mirrorPoint.x );
1202 }
1203
1204 connections |= item->IsConnectable();
1205 m_frame->UpdateItem( item, false, true );
1206 }
1207 }
1208
1209 // Update R-Tree for modified items
1210 for( EDA_ITEM* selected : selection )
1211 updateItem( selected, true );
1212
1213 if( item->IsMoving() )
1214 {
1216 }
1217 else
1218 {
1219 EE_SELECTION selectionCopy = selection;
1220
1221 if( selection.IsHover() )
1223
1224 if( connections )
1225 {
1227 lwbTool->TrimOverLappingWires( commit, &selectionCopy );
1228 lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
1229
1230 m_frame->SchematicCleanUp( commit );
1231 }
1232
1233 if( !localCommit.Empty() )
1234 localCommit.Push( _( "Mirror" ) );
1235 }
1236
1237 return 0;
1238}
1239
1240
1241const std::vector<KICAD_T> swappableItems = {
1243 SCH_TEXT_T,
1256};
1257
1258
1260{
1262 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
1263
1264 // Sheet pins are special, we need to make sure if we have any sheet pins,
1265 // that we only have sheet pins, and that they have the same parent
1266 if( selection.CountType( SCH_SHEET_PIN_T ) > 0 )
1267 {
1268 if( !selection.OnlyContains( { SCH_SHEET_PIN_T } ) )
1269 return 0;
1270
1271 SCH_SHEET_PIN* firstPin = static_cast<SCH_SHEET_PIN*>( selection.Front() );
1272 SCH_SHEET* parent = firstPin->GetParent();
1273
1274 for( EDA_ITEM* item : selection )
1275 {
1276 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
1277
1278 if( pin->GetParent() != parent )
1279 return 0;
1280 }
1281 }
1282
1283 if( selection.Size() < 2 )
1284 return 0;
1285
1286 bool isMoving = selection.Front()->IsMoving();
1287 bool appendUndo = isMoving;
1288 bool connections = false;
1289
1290 SCH_SCREEN* screen = this->m_frame->GetScreen();
1291
1292 for( size_t i = 0; i < sorted.size() - 1; i++ )
1293 {
1294 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
1295 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
1296
1297 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
1298 std::swap( aPos, bPos );
1299
1300 saveCopyInUndoList( a, UNDO_REDO::CHANGED, appendUndo );
1301 appendUndo = true;
1302 saveCopyInUndoList( b, UNDO_REDO::CHANGED, appendUndo );
1303
1304 // Sheet pins need to have their sides swapped before we change their
1305 // positions
1306 if( a->Type() == SCH_SHEET_PIN_T )
1307 {
1308 SCH_SHEET_PIN* aPin = static_cast<SCH_SHEET_PIN*>( a );
1309 SCH_SHEET_PIN* bPin = static_cast<SCH_SHEET_PIN*>( b );
1310 SHEET_SIDE aSide = aPin->GetSide(), bSide = bPin->GetSide();
1311 std::swap( aSide, bSide );
1312 aPin->SetSide( aSide );
1313 bPin->SetSide( bSide );
1314 }
1315
1316 a->SetPosition( aPos );
1317 b->SetPosition( bPos );
1318
1319 if( a->Type() == b->Type() )
1320 {
1321 switch( a->Type() )
1322 {
1323 case SCH_LABEL_T:
1324 case SCH_GLOBAL_LABEL_T:
1325 case SCH_HIER_LABEL_T:
1327 m_frame->AutoRotateItem( screen, a );
1328 m_frame->AutoRotateItem( screen, b );
1329 break;
1330 case SCH_SYMBOL_T:
1331 {
1332 SCH_SYMBOL* aSymbol = static_cast<SCH_SYMBOL*>( a );
1333 SCH_SYMBOL* bSymbol = static_cast<SCH_SYMBOL*>( b );
1334 int aOrient = aSymbol->GetOrientation(), bOrient = bSymbol->GetOrientation();
1335 std::swap( aOrient, bOrient );
1336 aSymbol->SetOrientation( aOrient );
1337 bSymbol->SetOrientation( bOrient );
1338 break;
1339 }
1340 default: break;
1341 }
1342 }
1343
1344 connections |= a->IsConnectable();
1345 connections |= b->IsConnectable();
1346 m_frame->UpdateItem( a, false, true );
1347 m_frame->UpdateItem( b, false, true );
1348 }
1349
1350 // Update R-Tree for modified items
1351 for( EDA_ITEM* selected : selection )
1352 updateItem( selected, true );
1353
1354 if( isMoving )
1355 {
1357 }
1358 else
1359 {
1360 if( selection.IsHover() )
1362
1363 if( connections )
1365
1366 m_frame->OnModify();
1367 }
1368
1369 return 0;
1370}
1371
1372
1374{
1375 const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
1376
1377 if( sourceItems.empty() )
1378 return 0;
1379
1381
1382 SCH_COMMIT commit( m_toolMgr );
1383 EE_SELECTION newItems;
1384
1385 for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
1386 {
1387 SCH_ITEM* newItem = item->Duplicate();
1388 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
1389 bool restore_state = false;
1390
1391 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
1392 {
1393 // If incrementing tries to go below zero, tell user why the value is repeated
1394
1395 if( !label->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
1396 m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
1397 }
1398
1399 // If cloning a symbol then put into 'move' mode.
1400 if( newItem->Type() == SCH_SYMBOL_T )
1401 {
1402 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
1403 newItem->Move( cursorPos - newItem->GetPosition() );
1404 }
1405 else
1406 {
1409 }
1410
1411 // If cloning a sheet, check that we aren't going to create recursion
1412 if( newItem->Type() == SCH_SHEET_T )
1413 {
1414 SCH_SHEET_PATH* currentSheet = &m_frame->GetCurrentSheet();
1415 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( newItem );
1416
1417 if( m_frame->CheckSheetForRecursion( sheet, currentSheet ) )
1418 {
1419 // Clear out the filename so that the user can pick a new one
1420 sheet->SetFileName( wxEmptyString );
1421 sheet->GetScreen()->SetFileName( wxEmptyString );
1422 restore_state = !m_frame->EditSheetProperties( sheet, currentSheet, nullptr );
1423 }
1424 }
1425
1427 newItem->SetFlags( IS_NEW );
1428 m_frame->AddToScreen( newItem, m_frame->GetScreen() );
1429 commit.Added( newItem, m_frame->GetScreen() );
1430
1431 if( newItem->Type() == SCH_SYMBOL_T )
1432 {
1434 SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
1435 int annotateStartNum = projSettings.m_AnnotateStartNum;
1436
1437 if( annotate.automatic )
1438 {
1439 static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
1440 NULL_REPORTER reporter;
1442 (ANNOTATE_ORDER_T) annotate.sort_order,
1443 (ANNOTATE_ALGO_T) annotate.method, true /* recursive */,
1444 annotateStartNum, false, false, reporter );
1445 }
1446
1447 restore_state = !m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit );
1448 }
1449
1450 if( restore_state )
1451 {
1452 commit.Revert();
1453 }
1454 else
1455 {
1456 newItems.Add( newItem );
1457
1459 lwbTool->TrimOverLappingWires( &commit, &newItems );
1460 lwbTool->AddJunctionsIfNeeded( &commit, &newItems );
1461
1462 m_frame->SchematicCleanUp( &commit );
1463 commit.Push( _( "Repeat Item" ) );
1464 }
1465
1466 }
1467
1468 if( !newItems.Empty() )
1469 m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
1470
1471 for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
1472 m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
1473
1474 return 0;
1475}
1476
1477
1478static std::vector<KICAD_T> deletableItems =
1479{
1482 SCH_LINE_T,
1486 SCH_TEXT_T,
1496 SCH_FIELD_T, // Will be hidden
1498};
1499
1500
1502{
1503 SCH_SCREEN* screen = m_frame->GetScreen();
1504 std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection( deletableItems ).GetItems();
1505 SCH_COMMIT commit( m_toolMgr );
1506 std::vector<VECTOR2I> pts;
1507 bool updateHierarchy = false;
1508
1509 if( items.empty() )
1510 return 0;
1511
1512 // Don't leave a freed pointer in the selection
1514
1515 for( EDA_ITEM* item : items )
1516 item->ClearFlags( STRUCT_DELETED );
1517
1518 for( EDA_ITEM* item : items )
1519 {
1520 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1521
1522 if( !sch_item )
1523 continue;
1524
1525 if( sch_item->IsConnectable() )
1526 {
1527 std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
1528 pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1529 }
1530
1531 if( sch_item->Type() == SCH_JUNCTION_T )
1532 {
1533 sch_item->SetFlags( STRUCT_DELETED );
1534 // clean up junctions at the end
1535 }
1536 else if( sch_item->Type() == SCH_SHEET_PIN_T )
1537 {
1538 SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1539 SCH_SHEET* sheet = pin->GetParent();
1540
1541 if( !alg::contains( items, sheet ) )
1542 {
1543 commit.Modify( sheet, m_frame->GetScreen() );
1544 sheet->RemovePin( pin );
1545 }
1546 }
1547 else if( sch_item->Type() == SCH_FIELD_T )
1548 {
1549 commit.Modify( item, m_frame->GetScreen() );
1550 static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
1551 }
1552 else
1553 {
1554 sch_item->SetFlags( STRUCT_DELETED );
1555 commit.Remove( item, m_frame->GetScreen() );
1556 updateHierarchy |= ( sch_item->Type() == SCH_SHEET_T );
1557 }
1558 }
1559
1560 for( const VECTOR2I& point : pts )
1561 {
1562 SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1563
1564 if( !junction )
1565 continue;
1566
1567 if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1568 m_frame->DeleteJunction( &commit, junction );
1569 }
1570
1571 commit.Push( _( "Delete" ) );
1572
1573 if( updateHierarchy )
1575
1576 return 0;
1577}
1578
1579
1580#define HITTEST_THRESHOLD_PIXELS 5
1581
1582
1584{
1586
1588 m_pickerItem = nullptr;
1589
1590 // Deactivate other tools; particularly important if another PICKER is currently running
1591 Activate();
1592
1593 picker->SetCursor( KICURSOR::REMOVE );
1594 picker->SetSnapping( false );
1595
1596 picker->SetClickHandler(
1597 [this]( const VECTOR2D& aPosition ) -> bool
1598 {
1599 if( m_pickerItem )
1600 {
1602 selectionTool->UnbrightenItem( m_pickerItem );
1603 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1605 m_pickerItem = nullptr;
1606 }
1607
1608 return true;
1609 } );
1610
1611 picker->SetMotionHandler(
1612 [this]( const VECTOR2D& aPos )
1613 {
1614 EE_COLLECTOR collector;
1615 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1616 collector.Collect( m_frame->GetScreen(), deletableItems, aPos );
1617
1619 selectionTool->GuessSelectionCandidates( collector, aPos );
1620
1621 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1622
1623 if( m_pickerItem != item )
1624 {
1625 if( m_pickerItem )
1626 selectionTool->UnbrightenItem( m_pickerItem );
1627
1628 m_pickerItem = item;
1629
1630 if( m_pickerItem )
1631 selectionTool->BrightenItem( m_pickerItem );
1632 }
1633 } );
1634
1635 picker->SetFinalizeHandler(
1636 [this]( const int& aFinalState )
1637 {
1638 if( m_pickerItem )
1639 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
1640
1641 // Wake the selection tool after exiting to ensure the cursor gets updated
1643 } );
1644
1646
1647 return 0;
1648}
1649
1650
1652{
1653 KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1654 SCH_COMMIT commit( m_toolMgr );
1655
1656 // Save old symbol in undo list if not already in edit, or moving.
1657 if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1658 commit.Modify( aField, m_frame->GetScreen() );
1659
1660 if( parentType == SCH_SYMBOL_T && aField->GetId() == REFERENCE_FIELD )
1661 static_cast<SCH_ITEM*>( aField->GetParent() )->SetConnectivityDirty();
1662
1663 wxString caption;
1664
1665 // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1666 if( parentType == SCH_SYMBOL_T && aField->GetId() >= 0 && aField->GetId() < MANDATORY_FIELDS )
1667 {
1668 wxString translated_fieldname;
1669 translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(),
1670 DO_TRANSLATE );
1671 caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
1672 }
1673 else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
1674 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1675 else
1676 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1677
1678 DIALOG_SCH_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1679
1680 // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1681 if( dlg.ShowQuasiModal() != wxID_OK )
1682 return;
1683
1684 dlg.UpdateField( &commit, aField, &m_frame->GetCurrentSheet() );
1685
1686 if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1687 static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1688
1689 if( !commit.Empty() )
1690 commit.Push( caption, SKIP_CONNECTIVITY );
1691}
1692
1693
1695{
1696 EE_SELECTION sel;
1697
1698 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1700 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1702 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1704
1705 if( sel.Size() != 1 )
1706 return 0;
1707
1708 bool clearSelection = sel.IsHover();
1709 EDA_ITEM* item = sel.Front();
1710
1711 if( item->Type() == SCH_SYMBOL_T )
1712 {
1713 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1714
1715 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1717 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1718 editFieldText( symbol->GetField( VALUE_FIELD ) );
1719 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1721 }
1722 else if( item->Type() == SCH_FIELD_T )
1723 {
1724 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1725
1726 editFieldText( field );
1727
1728 if( !field->IsVisible() )
1729 clearSelection = true;
1730 }
1731
1732 if( clearSelection )
1734
1735 return 0;
1736}
1737
1738
1740{
1742 SCH_COMMIT commit( m_toolMgr );
1743 SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1744 bool moving = head && head->IsMoving();
1745
1746 if( selection.Empty() )
1747 return 0;
1748
1749 std::vector<SCH_ITEM*> autoplaceItems;
1750
1751 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1752 {
1753 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1754
1755 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
1756 autoplaceItems.push_back( item );
1757 else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
1758 autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
1759 }
1760
1761 for( SCH_ITEM* sch_item : autoplaceItems )
1762 {
1763 if( !moving && !sch_item->IsNew() )
1764 commit.Modify( sch_item, m_frame->GetScreen() );
1765
1766 sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1767
1768 updateItem( sch_item, true );
1769 }
1770
1771 if( moving )
1772 {
1774 }
1775 else
1776 {
1777 if( !commit.Empty() )
1778 commit.Push( _( "Autoplace Fields" ) );
1779
1780 if( selection.IsHover() )
1782 }
1783
1784 return 0;
1785}
1786
1787
1789{
1790 SCH_SYMBOL* selectedSymbol = nullptr;
1792
1793 if( !selection.Empty() )
1794 selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1795
1797
1798 if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1799 || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1800 {
1802 }
1803
1804 DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1805
1806 dlg.ShowQuasiModal();
1807
1808 return 0;
1809}
1810
1811
1813{
1815
1816 if( selection.Empty() )
1817 return 0;
1818
1819 SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1820
1822 && symbol->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1823 {
1824 return 0;
1825 }
1826
1829 {
1830 return 0;
1831 }
1832
1833 if( !symbol->IsNew() )
1834 saveCopyInUndoList( symbol, UNDO_REDO::CHANGED );
1835
1836 m_frame->ConvertPart( symbol );
1837
1838 if( symbol->IsNew() )
1840
1841 if( selection.IsHover() )
1843
1844 return 0;
1845}
1846
1847
1849{
1851 bool clearSelection = selection.IsHover();
1852
1853 if( selection.Empty() )
1854 {
1855 if( getView()->IsLayerVisible( LAYER_SCHEMATIC_DRAWINGSHEET ) )
1856 {
1858 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1859
1860 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1862 }
1863
1864 return 0;
1865 }
1866
1867 EDA_ITEM* curr_item = selection.Front();
1868
1869 switch( curr_item->Type() )
1870 {
1871 case SCH_LINE_T:
1873 case SCH_JUNCTION_T:
1874 break;
1875
1876 default:
1877 if( selection.Size() > 1 )
1878 return 0;
1879
1880 break;
1881 }
1882
1883 switch( curr_item->Type() )
1884 {
1885 case SCH_SYMBOL_T:
1886 {
1887 int retval;
1888 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( curr_item );
1889
1890 // This needs to be scoped so the dialog destructor removes blocking status
1891 // before we launch the next dialog.
1892 {
1893 DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1894
1895 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1896 // frame. Therefore this dialog as a modal frame parent, MUST be run under
1897 // quasimodal mode for the quasimodal frame support to work. So don't use
1898 // the QUASIMODAL macros here.
1899 retval = symbolPropsDialog.ShowQuasiModal();
1900 }
1901
1902 if( retval == SYMBOL_PROPS_EDIT_OK )
1903 {
1906
1907 m_frame->OnModify();
1908 }
1909 else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1910 {
1912 true );
1913
1914 wxCHECK( editor, 0 );
1915
1916 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1917 blocking_win->Close( true );
1918
1919 // The broken library symbol link indicator cannot be edited.
1920 if( symbol->IsMissingLibSymbol() )
1921 return 0;
1922
1923 editor->LoadSymbolFromSchematic( symbol );
1924
1925 editor->Show( true );
1926 editor->Raise();
1927 }
1928 else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1929 {
1931 true );
1932
1933 wxCHECK( editor, 0 );
1934
1935 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1936 blocking_win->Close( true );
1937
1938 editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
1939
1940 editor->Show( true );
1941 editor->Raise();
1942 }
1943 else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1944 {
1946 dlg.ShowQuasiModal();
1947 }
1948 else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1949 {
1951 dlg.ShowQuasiModal();
1952 }
1953
1954 break;
1955 }
1956
1957 case SCH_SHEET_T:
1958 {
1959 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( curr_item );
1960 bool doClearAnnotation;
1961 bool doRefresh = false;
1962
1963 // Keep track of existing sheet paths. EditSheet() can modify this list.
1964 // Note that we use the validity checking/repairing version here just to make sure
1965 // we've got a valid hierarchy to begin with.
1966 SCH_SHEET_LIST originalHierarchy( &m_frame->Schematic().Root(), true );
1967
1968 doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1969 &doClearAnnotation );
1970
1971 // If the sheet file is changed and new sheet contents are loaded then we have to
1972 // clear the annotations on the new content (as it may have been set from some other
1973 // sheet path reference)
1974 if( doClearAnnotation )
1975 {
1976 SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1977
1978 // We clear annotation of new sheet paths here:
1979 screensList.ClearAnnotationOfNewSheetPaths( originalHierarchy );
1980
1981 // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1982 // path, but symbols managed by its sheet path must have their annotation cleared
1983 // because they are new:
1984 sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet(), false );
1985 }
1986
1987 if( doRefresh )
1988 {
1991 }
1992
1993 break;
1994 }
1995
1996 case SCH_SHEET_PIN_T:
1997 {
1998 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( curr_item );
2000
2001 // QuasiModal required for help dialog
2002 if( dlg.ShowQuasiModal() == wxID_OK )
2003 m_frame->OnModify();
2004
2005 break;
2006 }
2007
2008 case SCH_TEXT_T:
2009 case SCH_TEXTBOX_T:
2010 {
2011 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
2012
2013 // QuasiModal required for syntax help and Scintilla auto-complete
2014 if( dlg.ShowQuasiModal() == wxID_OK )
2015 m_frame->OnModify();
2016 }
2017 break;
2018
2019 case SCH_LABEL_T:
2020 case SCH_GLOBAL_LABEL_T:
2021 case SCH_HIER_LABEL_T:
2023 {
2024 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( curr_item ) );
2025
2026 // Must be quasi modal for syntax help
2027 if( dlg.ShowQuasiModal() == wxID_OK )
2028 m_frame->OnModify();
2029
2030 break;
2031 }
2032
2033 case SCH_FIELD_T:
2034 {
2035 SCH_FIELD* field = static_cast<SCH_FIELD*>( curr_item );
2036
2037 editFieldText( field );
2038
2039 if( !field->IsVisible() )
2040 clearSelection = true;
2041
2042 break;
2043 }
2044
2045 case SCH_SHAPE_T:
2046 {
2047 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
2048
2049 if( dlg.ShowModal() == wxID_OK )
2050 m_frame->OnModify();
2051
2052 break;
2053 }
2054
2055 case SCH_BITMAP_T:
2056 {
2057 SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( curr_item );
2058 DIALOG_IMAGE_PROPERTIES dlg( m_frame, bitmap );
2059
2060 if( dlg.ShowModal() == wxID_OK )
2061 {
2062 // The bitmap is cached in Opengl: clear the cache in case it has become invalid
2064 m_frame->OnModify();
2065 }
2066
2067 break;
2068 }
2069
2070 case SCH_LINE_T:
2072 case SCH_JUNCTION_T:
2073 if( std::all_of( selection.Items().begin(), selection.Items().end(),
2074 [&]( const EDA_ITEM* item )
2075 {
2076 return item->Type() == SCH_LINE_T
2077 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
2078 } ) )
2079 {
2080 std::deque<SCH_LINE*> lines;
2081
2082 for( EDA_ITEM* selItem : selection.Items() )
2083 lines.push_back( static_cast<SCH_LINE*>( selItem ) );
2084
2085 DIALOG_LINE_PROPERTIES dlg( m_frame, lines );
2086
2087 if( dlg.ShowModal() == wxID_OK )
2088 m_frame->OnModify();
2089 }
2090 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
2091 [&]( const EDA_ITEM* item )
2092 {
2093 return item->Type() == SCH_JUNCTION_T;
2094 } ) )
2095 {
2096 std::deque<SCH_JUNCTION*> junctions;
2097
2098 for( EDA_ITEM* selItem : selection.Items() )
2099 junctions.push_back( static_cast<SCH_JUNCTION*>( selItem ) );
2100
2101 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
2102
2103 if( dlg.ShowModal() == wxID_OK )
2104 m_frame->OnModify();
2105 }
2106 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
2107 [&]( const EDA_ITEM* item )
2108 {
2109 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
2110
2111 wxCHECK( schItem, false );
2112
2113 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
2114 || item->Type() == SCH_JUNCTION_T;
2115 } ) )
2116 {
2117 std::deque<SCH_ITEM*> items;
2118
2119 for( EDA_ITEM* selItem : selection.Items() )
2120 items.push_back( static_cast<SCH_ITEM*>( selItem ) );
2121
2122 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, items );
2123
2124 if( dlg.ShowModal() == wxID_OK )
2125 m_frame->OnModify();
2126 }
2127 else
2128 {
2129 return 0;
2130 }
2131
2132 break;
2133
2134 case SCH_MARKER_T: // These items have no properties to edit
2135 case SCH_NO_CONNECT_T:
2136 break;
2137
2138 default: // Unexpected item
2139 wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + curr_item->GetClass() );
2140 }
2141
2142 updateItem( curr_item, true );
2143
2144 if( clearSelection )
2146
2147 return 0;
2148}
2149
2150
2152{
2153 KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
2155 SCH_TEXT_T,
2156 SCH_TEXTBOX_T } );
2157 SCH_COMMIT commit( m_toolMgr );
2158
2159 for( unsigned int i = 0; i < selection.GetSize(); ++i )
2160 {
2161 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( selection.GetItem( i ) );
2162
2163 if( item && item->Type() != convertTo )
2164 {
2165 EDA_TEXT* sourceText = dynamic_cast<EDA_TEXT*>( item );
2166 bool selected = item->IsSelected();
2167 SCH_ITEM* newtext = nullptr;
2168 VECTOR2I position = item->GetPosition();
2169 wxString txt;
2170 wxString href;
2172 LABEL_FLAG_SHAPE shape = LABEL_FLAG_SHAPE::L_UNSPECIFIED;
2173
2174 switch( item->Type() )
2175 {
2176 case SCH_LABEL_T:
2177 case SCH_GLOBAL_LABEL_T:
2178 case SCH_HIER_LABEL_T:
2179 {
2180 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
2181
2182 txt = UnescapeString( label->GetText() );
2183 spinStyle = label->GetSpinStyle();
2184 shape = label->GetShape();
2185 href = label->GetHyperlink();
2186 break;
2187 }
2188
2190 {
2191 SCH_DIRECTIVE_LABEL* dirlabel = static_cast<SCH_DIRECTIVE_LABEL*>( item );
2192
2193 // a SCH_DIRECTIVE_LABEL has no text
2194 txt = _( "<empty>" );
2195
2196 spinStyle = dirlabel->GetSpinStyle();
2197 href = dirlabel->GetHyperlink();
2198 break;
2199 }
2200
2201 case SCH_TEXT_T:
2202 {
2203 SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
2204
2205 txt = text->GetText();
2206 href = text->GetHyperlink();
2207 break;
2208 }
2209
2210 case SCH_TEXTBOX_T:
2211 {
2212 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
2213 BOX2I bbox = textbox->GetBoundingBox();
2214
2215 bbox.Inflate( -textbox->GetTextMargin() );
2216
2217 if( convertTo == SCH_LABEL_T
2218 || convertTo == SCH_HIER_LABEL_T
2219 || convertTo == SCH_GLOBAL_LABEL_T )
2220 {
2221 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
2222 wxCHECK( text, 0 );
2223 int textSize = text->GetTextSize().y;
2224 bbox.Inflate( KiROUND( item->Schematic()->Settings().m_LabelSizeRatio * textSize ) );
2225 }
2226
2227 txt = textbox->GetText();
2228
2229 if( textbox->GetTextAngle().IsVertical() )
2230 {
2231 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2232 {
2233 spinStyle = SPIN_STYLE::SPIN::BOTTOM;
2234 position = VECTOR2I( bbox.Centre().x, bbox.GetOrigin().y );
2235 }
2236 else
2237 {
2238 spinStyle = SPIN_STYLE::SPIN::UP;
2239 position = VECTOR2I( bbox.Centre().x, bbox.GetEnd().y );
2240 }
2241 }
2242 else
2243 {
2244 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2245 {
2246 spinStyle = SPIN_STYLE::SPIN::LEFT;
2247 position = VECTOR2I( bbox.GetEnd().x, bbox.Centre().y );
2248 }
2249 else
2250 {
2251 spinStyle = SPIN_STYLE::SPIN::RIGHT;
2252 position = VECTOR2I( bbox.GetOrigin().x, bbox.Centre().y );
2253 }
2254 }
2255
2256 position = m_frame->GetNearestGridPosition( position );
2257 href = textbox->GetHyperlink();
2258 break;
2259 }
2260
2261 default:
2262 UNIMPLEMENTED_FOR( item->GetClass() );
2263 break;
2264 }
2265
2266 auto getValidNetname =
2267 []( const wxString& aText )
2268 {
2269 wxString local_txt = aText;
2270 local_txt.Replace( "\n", "_" );
2271 local_txt.Replace( "\r", "_" );
2272 local_txt.Replace( "\t", "_" );
2273
2274 // Bus groups can have spaces; bus vectors and signal names cannot
2275 if( !NET_SETTINGS::ParseBusGroup( aText, nullptr, nullptr ) )
2276 local_txt.Replace( " ", "_" );
2277
2278 // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
2279 local_txt = EscapeString( local_txt, CTX_NETNAME );
2280
2281 if( local_txt.IsEmpty() )
2282 return _( "<empty>" );
2283 else
2284 return local_txt;
2285 };
2286
2287 switch( convertTo )
2288 {
2289 case SCH_LABEL_T:
2290 {
2291 SCH_LABEL_BASE* new_label = new SCH_LABEL( position, getValidNetname( txt ) );
2292
2293 new_label->SetShape( shape );
2294 new_label->SetAttributes( *sourceText, false );
2295 new_label->SetSpinStyle( spinStyle );
2296 new_label->SetHyperlink( href );
2297 newtext = new_label;
2298 break;
2299 }
2300
2301 case SCH_GLOBAL_LABEL_T:
2302 {
2303 SCH_LABEL_BASE* new_label = new SCH_GLOBALLABEL( position, getValidNetname( txt ) );
2304
2305 new_label->SetShape( shape );
2306 new_label->SetAttributes( *sourceText, false );
2307 new_label->SetSpinStyle( spinStyle );
2308 new_label->SetHyperlink( href );
2309 newtext = new_label;
2310 break;
2311 }
2312
2313 case SCH_HIER_LABEL_T:
2314 {
2315 SCH_LABEL_BASE* new_label = new SCH_HIERLABEL( position, getValidNetname( txt ) );
2316
2317 new_label->SetShape( shape );
2318 new_label->SetAttributes( *sourceText, false );
2319 new_label->SetSpinStyle( spinStyle );
2320 new_label->SetHyperlink( href );
2321 newtext = new_label;
2322 break;
2323 }
2324
2326 {
2327 SCH_LABEL_BASE* new_label = new SCH_DIRECTIVE_LABEL( position );
2328
2329 // A SCH_DIRECTIVE_LABEL usually has at least one field containing the net class
2330 // name. If we're copying from a text object assume the text is the netclass
2331 // name. Otherwise, we'll just copy the fields which will either have a netclass
2332 // or not.
2333 if( !dynamic_cast<SCH_LABEL_BASE*>( item ) )
2334 {
2335 SCH_FIELD netclass( position, 0, new_label, wxT( "Netclass" ) );
2336 netclass.SetText( txt );
2337 netclass.SetVisible( true );
2338 new_label->GetFields().push_back( netclass );
2339 }
2340
2341 new_label->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
2342 new_label->SetAttributes( *sourceText, false );
2343 new_label->SetSpinStyle( spinStyle );
2344 new_label->SetHyperlink( href );
2345 newtext = new_label;
2346 break;
2347 }
2348
2349 case SCH_TEXT_T:
2350 {
2351 SCH_TEXT* new_text = new SCH_TEXT( position, txt );
2352
2353 new_text->SetAttributes( *sourceText, false );
2354 new_text->SetHyperlink( href );
2355 newtext = new_text;
2356 break;
2357 }
2358
2359 case SCH_TEXTBOX_T:
2360 {
2361 SCH_TEXTBOX* new_textbox = new SCH_TEXTBOX( 0, FILL_T::NO_FILL, txt );
2362 BOX2I bbox = item->GetBoundingBox();
2363
2364 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
2365 bbox.Inflate( -label->GetLabelBoxExpansion() );
2366
2367 new_textbox->SetAttributes( *sourceText, false );
2368
2369 int margin = new_textbox->GetTextMargin();
2370 bbox.Inflate( margin );
2371
2372 VECTOR2I topLeft = bbox.GetPosition();
2373 VECTOR2I botRight = bbox.GetEnd();
2374
2375 // Add 1/20 of the margin at the end to reduce line-breaking changes.
2376 int slop = margin / 20;
2377
2378 if( sourceText->GetTextAngle() == ANGLE_VERTICAL )
2379 {
2380 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2381 botRight.y += slop;
2382 else
2383 topLeft.y -= slop;
2384 }
2385 else
2386 {
2387 if( sourceText->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
2388 topLeft.x -= slop;
2389 else
2390 botRight.x += slop;
2391 }
2392
2393 new_textbox->SetPosition( topLeft );
2394 new_textbox->SetEnd( botRight );
2395
2396 new_textbox->SetHyperlink( href );
2397 newtext = new_textbox;
2398 break;
2399 }
2400
2401 default:
2402 UNIMPLEMENTED_FOR( wxString::Format( "%d.", convertTo ) );
2403 break;
2404 }
2405
2406 wxCHECK2( newtext, continue );
2407
2408 // Copy the old text item settings to the new one. Justifications are not copied
2409 // because they are not used in labels. Justifications will be set to default value
2410 // in the new text item type.
2411 //
2412 newtext->SetFlags( item->GetEditFlags() );
2413
2414 EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( item );
2415 EDA_TEXT* new_eda_text = dynamic_cast<EDA_TEXT*>( newtext );
2416
2417 wxCHECK2( eda_text && new_eda_text, continue );
2418
2419 new_eda_text->SetFont( eda_text->GetFont() );
2420 new_eda_text->SetTextSize( eda_text->GetTextSize() );
2421 new_eda_text->SetTextThickness( eda_text->GetTextThickness() );
2422 new_eda_text->SetItalic( eda_text->IsItalic() );
2423 new_eda_text->SetBold( eda_text->IsBold() );
2424
2425 newtext->AutoplaceFields( m_frame->GetScreen(), false );
2426
2427 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item );
2428 SCH_LABEL_BASE* new_label = dynamic_cast<SCH_LABEL_BASE*>( newtext );
2429
2430 if( label && new_label )
2431 {
2432 new_label->AddFields( label->GetFields() );
2433
2434 // A SCH_GLOBALLABEL has a specific field, that has no meaning for
2435 // other labels, and expected to be the first field in list.
2436 // It is the first field in list for this kind of label
2437 // So remove field named "Intersheetrefs" if exists for other labels
2438 int min_idx = new_label->Type() == SCH_GLOBAL_LABEL_T ? 1 : 0;
2439 std::vector<SCH_FIELD>& fields = new_label->GetFields();
2440
2441 for( int ii = fields.size()-1; ii >= min_idx; ii-- )
2442 {
2443 if( fields[ii].GetCanonicalName() == wxT( "Intersheetrefs" ) )
2444 fields.erase( fields.begin() + ii );
2445 }
2446 }
2447
2448 if( selected )
2450
2451 if( !item->IsNew() )
2452 {
2454 commit.Removed( item, m_frame->GetScreen() );
2455
2456 m_frame->AddToScreen( newtext, m_frame->GetScreen() );
2457 commit.Added( newtext, m_frame->GetScreen() );
2458 }
2459
2460 if( selected )
2462
2463 // Otherwise, pointer is owned by the undo stack
2464 if( item->IsNew() )
2465 delete item;
2466 }
2467 }
2468
2469 if( !commit.Empty() )
2470 commit.Push( _( "Change To" ) );
2471
2472 if( selection.IsHover() )
2474
2475 return 0;
2476}
2477
2478
2480{
2481 bool isSlice = aEvent.Matches( EE_ACTIONS::slice.MakeEvent() );
2484 SCH_SCREEN* screen = m_frame->GetScreen();
2485 SCH_COMMIT commit( m_toolMgr );
2486 std::vector<SCH_LINE*> lines;
2487
2488 for( EDA_ITEM* item : selection )
2489 {
2490 if( item->Type() == SCH_LINE_T )
2491 {
2492 SCH_LINE* line = static_cast<SCH_LINE*>( item );
2493
2494 if( !line->IsEndPoint( cursorPos ) )
2495 lines.push_back( line );
2496 }
2497 }
2498
2500
2501 for( SCH_LINE* line : lines )
2502 {
2503 SCH_LINE* newLine;
2504
2505 // We let the user select the break point if they're on a single line
2506 if( lines.size() == 1 && line->HitTest( cursorPos ) )
2507 m_frame->BreakSegment( &commit, line, cursorPos, &newLine, screen );
2508 else
2509 m_frame->BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
2510
2511 // Make sure both endpoints are deselected
2512 newLine->ClearFlags();
2513
2515 line->SetFlags( ENDPOINT );
2516
2517 // If we're a break, we want to drag both wires.
2518 // Side note: the drag/move tool only checks whether the first item is
2519 // new to determine if it should append undo or not, someday this should
2520 // be cleaned up and explictly controlled but for now the newLine
2521 // selection addition must be after the existing line.
2522 if( !isSlice )
2523 {
2524 m_selectionTool->AddItemToSel( newLine );
2525 newLine->SetFlags( STARTPOINT );
2526 }
2527 }
2528
2529 if( !lines.empty() )
2530 {
2532
2533 if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::drag, &commit, isSlice ) )
2534 commit.Push( isSlice ? _( "Slice Wire" ) : _( "Break Wire" ) );
2535 else
2536 commit.Revert();
2537 }
2538
2539 return 0;
2540}
2541
2542
2544{
2546 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2547
2548 if( !sheet || !sheet->HasUndefinedPins() )
2549 return 0;
2550
2551 if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
2552 return 0;
2553
2554 saveCopyInUndoList( sheet, UNDO_REDO::CHANGED );
2555
2556 sheet->CleanupSheet();
2557
2558 updateItem( sheet, true );
2559 m_frame->OnModify();
2560
2561 if( selection.IsHover() )
2563
2564 return 0;
2565}
2566
2567
2569{
2571
2572 if( selection.GetSize() > 1 )
2573 return 0;
2574
2575 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2576
2578
2579 SCH_SCREEN* screen;
2580
2581 if( sheet )
2582 {
2583 // When changing the page number of a selected sheet, the current screen owns the sheet.
2584 screen = m_frame->GetScreen();
2585
2586 instance.push_back( sheet );
2587 }
2588 else
2589 {
2590 SCH_SHEET_PATH prevInstance = instance;
2591
2592 // When change the page number in the screen, the previous screen owns the sheet.
2593 if( prevInstance.size() )
2594 {
2595 prevInstance.pop_back();
2596 screen = prevInstance.LastScreen();
2597 }
2598 else
2599 {
2600 // The root sheet and root screen are effectively the same thing.
2601 screen = m_frame->GetScreen();
2602 }
2603
2604 sheet = m_frame->GetCurrentSheet().Last();
2605 }
2606
2607 wxString msg;
2608 wxString sheetPath = instance.PathHumanReadable( false );
2609 wxString pageNumber = instance.GetPageNumber();
2610
2611 msg.Printf( _( "Enter page number for sheet path%s" ),
2612 ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
2613
2614 wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
2615
2616 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
2617
2618 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
2619 return 0;
2620
2621 m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
2622
2623 instance.SetPageNumber( dlg.GetValue() );
2624
2625 if( instance == m_frame->GetCurrentSheet() )
2626 {
2627 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
2629 }
2630
2631 m_frame->OnModify();
2632
2633 return 0;
2634}
2635
2636
2638{
2639 wxString aFileName = *aEvent.Parameter<wxString*>();
2640 return ( m_frame->AddSheetAndUpdateDisplay( aFileName ) ? 0 : 1 );
2641}
2642
2643
2645{
2647 SCH_COMMIT commit( m_toolMgr );
2648
2649 if( selection.Empty() )
2650 return 0;
2651
2652 for( EDA_ITEM* item : selection )
2653 {
2654 if( item->Type() == SCH_SYMBOL_T )
2655 {
2656 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2657
2658 commit.Modify( symbol, m_frame->GetScreen() );
2659
2660 if( aEvent.IsAction( &EE_ACTIONS::setDNP ) )
2661 symbol->SetDNP( true );
2662
2664 symbol->SetExcludedFromSim( true );
2665
2667 symbol->SetExcludedFromBOM( true );
2668
2670 symbol->SetExcludedFromBoard( true );
2671 }
2672 }
2673
2674 if( !commit.Empty() )
2675 commit.Push( _( "Set Attribute" ) );
2676
2677 return 0;
2678}
2679
2680
2682{
2684 SCH_COMMIT commit( m_toolMgr );
2685
2686 if( selection.Empty() )
2687 return 0;
2688
2689 for( EDA_ITEM* item : selection )
2690 {
2691 if( item->Type() == SCH_SYMBOL_T )
2692 {
2693 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2694
2695 commit.Modify( symbol, m_frame->GetScreen() );
2696
2697 if( aEvent.IsAction( &EE_ACTIONS::unsetDNP ) )
2698 symbol->SetDNP( false );
2699
2701 symbol->SetExcludedFromSim( false );
2702
2704 symbol->SetExcludedFromBOM( false );
2705
2707 symbol->SetExcludedFromBoard( false );
2708 }
2709 }
2710
2711 if( !commit.Empty() )
2712 commit.Push( _( "Clear Attribute" ) );
2713
2714 return 0;
2715}
2716
2717
2719{
2721 SCH_COMMIT commit( m_toolMgr );
2722
2723 if( selection.Empty() )
2724 return 0;
2725
2726 for( EDA_ITEM* item : selection )
2727 {
2728 if( item->Type() == SCH_SYMBOL_T )
2729 {
2730 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2731
2732 commit.Modify( symbol, m_frame->GetScreen() );
2733
2734 if( aEvent.IsAction( &EE_ACTIONS::toggleDNP ) )
2735 symbol->SetDNP( !symbol->GetDNP() );
2736
2738 symbol->SetExcludedFromSim( !symbol->GetExcludedFromSim() );
2739
2741 symbol->SetExcludedFromBOM( !symbol->GetExcludedFromBOM() );
2742
2744 symbol->SetExcludedFromBoard( !symbol->GetExcludedFromBoard() );
2745 }
2746 }
2747
2748 if( !commit.Empty() )
2749 commit.Push( _( "Toggle Attribute" ) );
2750
2751 return 0;
2752
2753}
2754
2755
2757{
2763 Go( &SCH_EDIT_TOOL::Swap, EE_ACTIONS::swap.MakeEvent() );
2766
2785
2788
2801
2805
2807}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
static TOOL_ACTION paste
Definition: actions.h:69
static TOOL_ACTION unselectAll
Definition: actions.h:72
static TOOL_ACTION copy
Definition: actions.h:68
static TOOL_ACTION pickerTool
Definition: actions.h:165
static TOOL_ACTION pasteSpecial
Definition: actions.h:70
static TOOL_ACTION pageSettings
Definition: actions.h:56
static TOOL_ACTION duplicate
Definition: actions.h:73
static TOOL_ACTION doDelete
Definition: actions.h:74
static TOOL_ACTION deleteTool
Definition: actions.h:75
static TOOL_ACTION cut
Definition: actions.h:67
static TOOL_ACTION refreshPreview
Definition: actions.h:113
static TOOL_ACTION selectAll
Definition: actions.h:71
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:91
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:77
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
const Vec & GetPosition() const
Definition: box2.h:185
const Vec & GetOrigin() const
Definition: box2.h:184
const Vec GetCenter() const
Definition: box2.h:196
const Vec GetEnd() const
Definition: box2.h:186
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
Vec Centre() const
Definition: box2.h:71
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:90
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition: commit.h:84
bool Empty() const
Returns status of an item.
Definition: commit.h:142
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:96
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.
Handle editing a single symbol field in the schematic editor.
void UpdateField(SCH_COMMIT *aCommit, SCH_FIELD *aField, SCH_SHEET_PATH *aSheetPath)
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:174
bool IsVertical() const
Definition: eda_angle.h:179
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:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:239
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:240
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:129
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:125
bool IsSelected() const
Definition: eda_item.h:106
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:172
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:127
virtual wxString GetClass() const =0
Return the class name.
bool IsMoving() const
Definition: eda_item.h:104
bool IsNew() const
Definition: eda_item.h:103
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:155
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:80
void SetTextSize(VECTOR2I aNewSize)
Definition: eda_text.cpp:358
bool IsItalic() const
Definition: eda_text.h:141
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:131
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
virtual bool IsVisible() const
Definition: eda_text.h:147
KIFONT::FONT * GetFont() const
Definition: eda_text.h:207
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:276
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:260
wxString GetHyperlink() const
Definition: eda_text.h:358
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:229
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsBold() const
Definition: eda_text.h:144
void SetHyperlink(wxString aLink)
Definition: eda_text.h:359
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:205
int GetTextThickness() const
Definition: eda_text.h:123
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:342
VECTOR2I GetTextSize() const
Definition: eda_text.h:218
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:252
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:194
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:189
static TOOL_ACTION unsetExcludeFromSimulation
Definition: ee_actions.h:188
static TOOL_ACTION setExcludeFromBoard
Definition: ee_actions.h:190
static TOOL_ACTION move
Definition: ee_actions.h:121
static TOOL_ACTION clearHighlight
Definition: ee_actions.h:285
static TOOL_ACTION toGLabel
Definition: ee_actions.h:141
static TOOL_ACTION toggleExcludeFromBoard
Definition: ee_actions.h:192
static TOOL_ACTION setDNP
Definition: ee_actions.h:193
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:227
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:186
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:185
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:172
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:291
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:216
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:93
static TOOL_ACTION setExcludeFromBOM
Definition: ee_actions.h:184
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:157
static TOOL_ACTION setExcludeFromSimulation
Definition: ee_actions.h:187
static TOOL_ACTION unsetExcludeFromBoard
Definition: ee_actions.h:191
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:228
static TOOL_ACTION toggleDNP
Definition: ee_actions.h:195
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 > EditableItems
Definition: ee_collectors.h:42
static const std::vector< KICAD_T > FieldOwners
Definition: ee_collectors.h:44
static SELECTION_CONDITION SingleSymbol
static SELECTION_CONDITION SingleMultiFunctionPin
static SELECTION_CONDITION SingleSymbolOrPower
static SELECTION_CONDITION SingleMultiUnitSymbol
static SELECTION_CONDITION AllPins
static SELECTION_CONDITION MultipleSymbolsOrPower
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 })
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:140
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:197
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:1400
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:53
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:432
@ BASE
Definition: lib_item.h:77
@ DEMORGAN
Definition: lib_item.h:77
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
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:83
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:72
void SetSnapping(bool aSnap)
Definition: picker_tool.h:65
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:63
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:103
void update() override
Update menu state stub.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
These settings were stored in SCH_BASE_FRAME previously.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
SCH_SHEET & Root() const
Definition: schematic.h:105
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:41
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:353
virtual void Revert() override
Definition: sch_commit.cpp:417
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 ConvertPart(SCH_SYMBOL *aSymbol)
Definition: picksymbol.cpp:126
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.
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy)
Verify that aSheet will not cause a recursion error in aHierarchy.
Definition: sheet.cpp:49
void SchematicCleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
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.
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 EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:585
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 UpdateHierarchyNavigator()
Update the hierarchy navigation tree and history.
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.
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
Definition: sch_edit_tool.h:98
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 ConvertDeMorgan(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:52
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:889
int GetId() const
Definition: sch_field.h:128
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1000
void SetText(const wxString &aText) override
Definition: sch_field.cpp:989
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:151
virtual bool IsConnectable() const
Definition: sch_item.h:372
virtual void MirrorVertically(int aCenter)=0
Mirror item vertically about aCenter.
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:161
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
virtual void MirrorHorizontally(int aCenter)=0
Mirror item horizontally about aCenter.
void ClearFieldsAutoplaced()
Definition: sch_item.h:456
virtual void Move(const VECTOR2I &aMoveVector)=0
Move the item by aMoveVector to a new position.
virtual void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Definition: sch_item.h:471
virtual void Rotate(const VECTOR2I &aCenter)=0
Rotate the item around aCenter 90 degrees in the clockwise direction.
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:465
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:484
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:387
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:94
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:166
void AddFields(const std::vector< SCH_FIELD > &aFields)
Definition: sch_label.h:204
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:372
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:168
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:167
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:191
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:337
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.)
int AddJunctionsIfNeeded(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Handle the addition of junctions to a selection of objects.
int TrimOverLappingWires(SCH_COMMIT *aCommit, EE_SELECTION *aSelection)
Logic to remove wires when overlapping correct items.
static bool IsDrawingLineWireOrBus(const SELECTION &aSelection)
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
void RotateEnd(const VECTOR2I &aCenter)
Definition: sch_line.cpp:425
void RotateStart(const VECTOR2I &aCenter)
Definition: sch_line.cpp:419
VECTOR2I GetEndPoint() const
Definition: sch_line.h:145
VECTOR2I GetStartPoint() const
Definition: sch_line.h:140
bool IsEndPoint(const VECTOR2I &aPoint) const
Definition: sch_line.h:94
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:688
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicates that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:486
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
SCH_ITEM * GetItem(const VECTOR2I &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:389
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:115
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear the annotation for the symbols in aSheetPath on the screen.
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:78
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_shape.h:75
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 Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:845
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:314
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
Schematic symbol object.
Definition: sch_symbol.h:81
int GetUnit() const
Definition: sch_symbol.h:228
void SetDNP(bool aDNP)
Definition: sch_symbol.h:746
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:857
void SetExcludedFromSim(bool aExclude) override
Definition: sch_symbol.h:737
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:940
int GetConvert() const
Definition: sch_symbol.h:270
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
bool GetExcludedFromBOM() const
Definition: sch_symbol.h:739
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:242
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
bool GetExcludedFromSim() const override
Definition: sch_symbol.h:736
void SetExcludedFromBOM(bool aIncludeInBOM)
Definition: sch_symbol.h:740
int GetOrientation() const
Get the display symbol orientation.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:175
bool GetExcludedFromBoard() const
Definition: sch_symbol.h:742
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:192
void SetExcludedFromBoard(bool aIncludeOnBoard)
Definition: sch_symbol.h:743
bool GetDNP() const
Definition: sch_symbol.h:745
int GetTextMargin() const
Definition: sch_textbox.cpp:68
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:109
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:121
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
void BrightenItem(EDA_ITEM *aItem)
int AddItemToSel(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:42
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:75
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:120
const std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:201
VECTOR2I GetReferencePoint() const
Definition: selection.h:252
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:93
bool IsHover() const
Definition: selection.h:83
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:99
EDA_ITEM * Front() const
Definition: selection.h:208
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:213
bool OnlyContains(std::vector< KICAD_T > aList) const
Checks if all items in the selection have a type in aList.
Definition: selection.cpp:191
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
bool HasReferencePoint() const
Definition: selection.h:247
size_t CountType(KICAD_T aType) const
Definition: selection.cpp:156
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.
bool IsCurrentTool(const TOOL_ACTION &aAction) const
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool DisableGridSnapping() const
Definition: tool_event.h:363
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:384
COMMIT * Commit() const
Returns information about difference between current mouse cursor position and the place where draggi...
Definition: tool_event.h:275
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:82
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:460
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
TOOL_MENU & GetToolMenu()
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
void Activate()
Run the tool.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:230
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:192
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:50
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
This file is part of the common library.
@ SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL
@ SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL
@ SYMBOL_PROPS_WANT_UPDATE_SYMBOL
@ SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL
@ SYMBOL_PROPS_EDIT_OK
#define _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:433
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:434
#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_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:388
#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
see class PGM_BASE
#define SKIP_CONNECTIVITY
Definition: sch_commit.h:43
@ SYM_MIRROR_Y
@ SYM_MIRROR_X
static std::vector< KICAD_T > deletableItems
const std::vector< KICAD_T > swappableItems
LABEL_FLAG_SHAPE
Definition: sch_label.h:91
ANNOTATE_ORDER_T
Schematic annotation order options.
@ ANNOTATE_SELECTION
Annotate the selection.
ANNOTATE_ALGO_T
Schematic annotation type options.
@ SHEET_MANDATORY_FIELDS
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
Definition: sch_sheet.h:49
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
Definition: sch_sheet_pin.h:46
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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:94
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".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ GR_TEXT_H_ALIGN_RIGHT
#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_LINE_T
Definition: typeinfo.h:146
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:143
@ SCH_FIELD_LOCATE_REFERENCE_T
Definition: typeinfo.h:164
@ SCH_FIELD_LOCATE_FOOTPRINT_T
Definition: typeinfo.h:166
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ SCH_FIELD_T
Definition: typeinfo.h:155
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:154
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_FIELD_LOCATE_VALUE_T
Definition: typeinfo.h:165
@ SCH_SHEET_T
Definition: typeinfo.h:158
@ SCH_MARKER_T
Definition: typeinfo.h:141
@ SCH_SHAPE_T
Definition: typeinfo.h:147
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:145
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:175
@ SCHEMATIC_T
Definition: typeinfo.h:188
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:157
@ SCH_TEXT_T
Definition: typeinfo.h:150
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:144
@ SCH_BITMAP_T
Definition: typeinfo.h:148
@ SCH_TEXTBOX_T
Definition: typeinfo.h:149
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
@ SCH_JUNCTION_T
Definition: typeinfo.h:142
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:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588