KiCad PCB EDA Suite
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-2022 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 <bitmaps.h>
34#include <confirm.h>
35#include <eda_item.h>
36#include <string_utils.h>
37#include <sch_item.h>
38#include <sch_symbol.h>
39#include <sch_shape.h>
40#include <sch_sheet.h>
41#include <sch_sheet_pin.h>
42#include <sch_text.h>
43#include <sch_textbox.h>
44#include <sch_bitmap.h>
45#include <sch_view.h>
46#include <sch_line.h>
47#include <sch_bus_entry.h>
48#include <sch_junction.h>
49#include <sch_edit_frame.h>
50#include <schematic.h>
52#include <eeschema_id.h>
54#include <dialogs/dialog_image_properties.h>
63#include <dialogs/dialog_text_properties.h>
64#include <pgm_base.h>
67#include <core/kicad_algo.h>
68#include <wx/textdlg.h>
70
72{
73public:
75 ACTION_MENU( true )
76 {
78 SetTitle( _( "Symbol Unit" ) );
79 }
80
81protected:
82 ACTION_MENU* create() const override
83 {
84 return new SYMBOL_UNIT_MENU();
85 }
86
87private:
88 void update() override
89 {
91 EE_SELECTION& selection = selTool->GetSelection();
92 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
93
94 Clear();
95
96 if( !symbol )
97 {
98 Append( ID_POPUP_SCH_SELECT_UNIT_CMP, _( "no symbol selected" ), wxEmptyString );
99 Enable( ID_POPUP_SCH_SELECT_UNIT_CMP, false );
100 return;
101 }
102
103 int unit = symbol->GetUnit();
104
105 if( !symbol->GetLibSymbolRef() || symbol->GetLibSymbolRef()->GetUnitCount() < 2 )
106 {
107 Append( ID_POPUP_SCH_SELECT_UNIT_CMP, _( "symbol is not multi-unit" ), wxEmptyString );
108 Enable( ID_POPUP_SCH_SELECT_UNIT_CMP, false );
109 return;
110 }
111
112 for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
113 {
114 wxString num_unit;
115 num_unit.Printf( _( "Unit %s" ), LIB_SYMBOL::SubReference( ii + 1, false ) );
116
117 wxMenuItem * item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
118 wxITEM_CHECK );
119 if( unit == ii + 1 )
120 item->Check(true);
121
122 // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_SYM_MAX
123 // See eeschema_id to modify this value.
125 break; // We have used all IDs for these submenus
126 }
127 }
128};
129
130
132 EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveEdit" )
133{
134 m_pickerItem = nullptr;
135}
136
137
139
141{
143
146
147 wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
148
149 auto hasElements =
150 [this]( const SELECTION& aSel )
151 {
152 return !m_frame->GetScreen()->Items().empty();
153 };
154
155 auto sheetHasUndefinedPins =
156 []( const SELECTION& aSel )
157 {
158 if( aSel.Size() == 1 && aSel.Front()->Type() == SCH_SHEET_T )
159 return static_cast<SCH_SHEET*>( aSel.Front() )->HasUndefinedPins();
160
161 return false;
162 };
163
164 auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
165
166 auto haveHighlight =
167 [&]( const SELECTION& sel )
168 {
169 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
170
171 return editFrame && editFrame->GetHighlightedConnection() != nullptr;
172 };
173
174 auto anyTextTool =
175 [this]( const SELECTION& aSel )
176 {
182 };
183
184 auto duplicateCondition =
185 []( const SELECTION& aSel )
186 {
188 return false;
189
190 return true;
191 };
192
193 auto orientCondition =
194 []( const SELECTION& aSel )
195 {
196 if( aSel.Empty() )
197 return false;
198
200 return false;
201
202 if( aSel.GetSize() > 1 )
203 return true;
204
205 SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
206
207 switch( item->Type() )
208 {
209 case SCH_MARKER_T:
210 case SCH_JUNCTION_T:
211 case SCH_NO_CONNECT_T:
212 case SCH_PIN_T:
213 return false;
214 case SCH_LINE_T:
215 return item->GetLayer() != LAYER_WIRE && item->GetLayer() != LAYER_BUS;
216 default:
217 return true;
218 }
219 };
220
221 auto propertiesCondition =
222 [&]( const SELECTION& aSel )
223 {
224 if( aSel.GetSize() == 0 )
225 {
227 {
230
231 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
232 return true;
233 }
234
235 return false;
236 }
237
238 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
239 const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
240
241 if( !firstItem || !eeSelection )
242 return false;
243
244 switch( firstItem->Type() )
245 {
246 case SCH_SYMBOL_T:
247 case SCH_SHEET_T:
248 case SCH_SHEET_PIN_T:
249 case SCH_TEXT_T:
250 case SCH_TEXTBOX_T:
251 case SCH_LABEL_T:
253 case SCH_HIER_LABEL_T:
255 case SCH_FIELD_T:
256 case SCH_SHAPE_T:
257 case SCH_BITMAP_T:
258 return aSel.GetSize() == 1;
259
260 case SCH_LINE_T:
262 case SCH_JUNCTION_T:
263 if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
264 [&]( const EDA_ITEM* item )
265 {
266 return item->Type() == SCH_LINE_T
267 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
268 } ) )
269 {
270 return true;
271 }
272 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
273 [&]( const EDA_ITEM* item )
274 {
275 return item->Type() == SCH_JUNCTION_T;
276 } ) )
277 {
278 return true;
279 }
280 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
281 [&]( const EDA_ITEM* item )
282 {
283 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
284
285 wxCHECK( schItem, false );
286
287 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
288 || item->Type() == SCH_JUNCTION_T;
289 } ) )
290 {
291 return true;
292 }
293
294 return false;
295
296 default:
297 return false;
298 }
299 };
300
301 auto autoplaceCondition =
302 []( const SELECTION& aSel )
303 {
304 for( const EDA_ITEM* item : aSel )
305 {
306 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
307 return true;
308 }
309
310 return false;
311 };
312
313 static std::vector<KICAD_T> allTextTypes = { SCH_LABEL_LOCATE_ANY_T, SCH_TEXT_T, SCH_TEXTBOX_T };
314
315 auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
316
317 auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_DIRECTIVE_LABEL_T,
321 SCH_TEXTBOX_T } ) )
322 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
323
324 auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
328 SCH_TEXTBOX_T } ) )
329 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
330
331 auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
335 SCH_TEXTBOX_T } ) )
336 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
337
338 auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
342 SCH_TEXTBOX_T } ) )
343 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
344
345 auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
349 SCH_TEXTBOX_T } ) )
350 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
351
352 auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
356 SCH_TEXT_T } ) )
357 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
358
359 auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_BUS_WIRE_ENTRY_T,
361
362 auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
363
364 //
365 // Add edit actions to the move tool menu
366 //
367 if( moveTool )
368 {
369 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
370
371 moveMenu.AddSeparator();
372 moveMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition );
373 moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition );
374 moveMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition );
375 moveMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition );
377
378 moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
379
380 CONDITIONAL_MENU* editMoveItemSubMenu = new CONDITIONAL_MENU(moveTool);
381 editMoveItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
382 editMoveItemSubMenu->SetIcon( BITMAPS::right );
383 moveMenu.AddMenu( editMoveItemSubMenu, E_C::SingleSymbol );
384
385 editMoveItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol );
386 editMoveItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol );
387 editMoveItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol );
388
390
391 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
392 symUnitMenu->SetTool( this );
393 m_menu.RegisterSubMenu( symUnitMenu );
394 moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
395
396 moveMenu.AddSeparator();
400 moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
401 }
402
403 //
404 // Add editing actions to the drawing tool menu
405 //
406 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
407
408 drawMenu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
409 drawMenu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
410
411 drawMenu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
412 drawMenu.AddSeparator( sheetSelection && EE_CONDITIONS::Idle, 1 );
413
414 drawMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
415 drawMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
416 drawMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
417 drawMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
418
419 drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
420
421 CONDITIONAL_MENU* editDrawItemSubMenu = new CONDITIONAL_MENU( drawingTools );
422 editDrawItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
423 editDrawItemSubMenu->SetIcon( BITMAPS::right );
424 drawMenu.AddMenu( editDrawItemSubMenu, E_C::SingleSymbol, 200 );
425
426 editDrawItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
427 editDrawItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
428 editDrawItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
429
431
432 drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
433
434 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
435 symUnitMenu2->SetTool( drawingTools );
436 drawingTools->GetToolMenu().RegisterSubMenu( symUnitMenu2 );
437 drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
438
440
441 drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
442 drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
443 drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
444 drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
445 drawMenu.AddItem( EE_ACTIONS::toTextBox, anyTextTool && E_C::Idle, 200 );
446
447 //
448 // Add editing actions to the selection tool menu
449 //
451
452 selToolMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
453 selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
454 selToolMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
455 selToolMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
457
458 selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
459
460 CONDITIONAL_MENU* editSelItemSubMenu = new CONDITIONAL_MENU( moveTool );
461 editSelItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
462 editSelItemSubMenu->SetIcon( BITMAPS::right );
463 selToolMenu.AddMenu( editSelItemSubMenu, E_C::SingleSymbol, 200 );
464
465 editSelItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
466 editSelItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
467 editSelItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
468
469 selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
471
472 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
473 symUnitMenu3->SetTool( m_selectionTool );
475 selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
476
480
481 CONDITIONAL_MENU* convertToSubMenu = new CONDITIONAL_MENU( m_selectionTool );
482 convertToSubMenu->SetTitle( _( "Change To" ) );
483 convertToSubMenu->SetIcon( BITMAPS::right );
484 selToolMenu.AddMenu( convertToSubMenu, toChangeCondition, 200 );
485
486 convertToSubMenu->AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
487 convertToSubMenu->AddItem( EE_ACTIONS::toCLabel, toCLabelCondition, 200 );
488 convertToSubMenu->AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
489 convertToSubMenu->AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
490 convertToSubMenu->AddItem( EE_ACTIONS::toText, toTextCondition, 200 );
491 convertToSubMenu->AddItem( EE_ACTIONS::toTextBox, toTextBoxCondition, 200 );
492
493 selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
494
495 selToolMenu.AddSeparator( 300 );
496 selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
497 selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
498 selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
499 selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
500 selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
501 selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
502
503 selToolMenu.AddSeparator( 400 );
504 selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
505
506
507 return true;
508}
509
510
511const std::vector<KICAD_T> rotatableItems = {
529};
530
531
533{
534 bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
536
537 if( selection.GetSize() == 0 )
538 return 0;
539
540 SCH_ITEM* head = nullptr;
541 int principalItemCount = 0; // User-selected items (as opposed to connected wires)
542 VECTOR2I rotPoint;
543 bool moving = false;
544
545 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
546 {
547 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
548
549 if( item->HasFlag( SELECTED_BY_DRAG ) )
550 continue;
551
552 principalItemCount++;
553
554 if( !head )
555 head = item;
556 }
557
558 if( head && head->IsMoving() )
559 moving = true;
560
561 if( principalItemCount == 1 )
562 {
563 if( moving && selection.HasReferencePoint() )
564 rotPoint = selection.GetReferencePoint();
565 else if( head->IsConnectable() )
566 rotPoint = head->GetPosition();
567 else
569
570 if( !moving )
572
573 switch( head->Type() )
574 {
575 case SCH_SYMBOL_T:
576 {
577 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
578
579 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
580 symbol->Rotate( rotPoint );
581
584
585 break;
586 }
587
588 case SCH_TEXT_T:
589 case SCH_LABEL_T:
591 case SCH_HIER_LABEL_T:
593 {
594 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
595 textItem->Rotate90( clockwise );
596 break;
597 }
598
599 case SCH_SHEET_PIN_T:
600 {
601 // Rotate pin within parent sheet
602 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
603 SCH_SHEET* sheet = pin->GetParent();
604
605 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
606 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
607
608 break;
609 }
610
611 case SCH_LINE_T:
612 {
613 SCH_LINE* line = static_cast<SCH_LINE*>( head );
614
615 // Equal checks for both and neither. We need this because on undo
616 // the item will have both flags cleared, but will be selected, so it is possible
617 // for the user to get a selected line with neither endpoint selected. We
618 // set flags to make sure Rotate() works when we call it.
619 if( line->HasFlag( STARTPOINT ) == line->HasFlag( ENDPOINT ) )
620 {
621 line->SetFlags( STARTPOINT | ENDPOINT );
622 // When we allow off grid items, the rotPoint should be set to the midpoint
623 // of the line to allow rotation around the center, and the next if
624 // should become an else-if
625 }
626
627 if( line->HasFlag( STARTPOINT ) )
628 rotPoint = line->GetEndPoint();
629 else if( line->HasFlag( ENDPOINT ) )
630 rotPoint = line->GetStartPoint();
631 }
632
636 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
637 head->Rotate( rotPoint );
638
639 break;
640
641 case SCH_FIELD_T:
642 {
643 SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
644
645 if( field->GetTextAngle().IsHorizontal() )
647 else
649
650 // Now that we're moving a field, they're no longer autoplaced.
651 static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
652
653 break;
654 }
655
656 case SCH_SHAPE_T:
657 case SCH_TEXTBOX_T:
658 for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
659 head->Rotate( rotPoint );
660
661 break;
662
663 case SCH_BITMAP_T:
664 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
665 head->Rotate( rotPoint );
666
667 // The bitmap is cached in Opengl: clear the cache to redraw
669 break;
670
671 case SCH_SHEET_T:
672 {
673 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
675
676 // Rotate the sheet on itself. Sheets do not have an anchor point.
677 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
678 sheet->Rotate( rotPoint );
679
680 break;
681 }
682
683 default:
684 UNIMPLEMENTED_FOR( head->GetClass() );
685 }
686
687 m_frame->UpdateItem( head, false, true );
688 }
689 else
690 {
691 if( moving && selection.HasReferencePoint() )
692 rotPoint = selection.GetReferencePoint();
693 else
694 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
695 }
696
697 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
698 {
699 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
700
701 // We've already rotated the user selected item if there was only one. We're just
702 // here to rotate the ends of wires that were attached to it.
703 if( principalItemCount == 1 && !item->HasFlag( SELECTED_BY_DRAG ) )
704 continue;
705
706 if( !moving )
707 saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
708
709 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
710 {
711 if( item->Type() == SCH_LINE_T )
712 {
713 SCH_LINE* line = (SCH_LINE*) item;
714
715 // If we are rotating more than one item, we do not have start/end
716 // points separately selected
717 if( item->HasFlag( STARTPOINT ) )
718 line->RotateStart( rotPoint );
719
720 if( item->HasFlag( ENDPOINT ) )
721 line->RotateEnd( rotPoint );
722 }
723 else if( item->Type() == SCH_SHEET_PIN_T )
724 {
725 if( item->GetParent()->IsSelected() )
726 {
727 // parent will rotate us
728 }
729 else
730 {
731 // rotate within parent
732 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
733 SCH_SHEET* sheet = pin->GetParent();
734
735 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
736 }
737 }
738 else if( item->Type() == SCH_FIELD_T )
739 {
740 if( item->GetParent()->IsSelected() )
741 {
742 // parent will rotate us
743 }
744 else
745 {
746 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
747
748 field->Rotate( rotPoint );
749
750 if( field->GetTextAngle().IsHorizontal() )
752 else
754
755 // Now that we're moving a field, they're no longer autoplaced.
756 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
757 }
758 }
759 else
760 {
761 item->Rotate( rotPoint );
762 }
763 }
764
765 m_frame->UpdateItem( item, false, true );
766 updateItem( item, true );
767 }
768
770
771 if( moving )
772 {
774 }
775 else
776 {
777 EE_SELECTION selectionCopy = selection;
778
779 if( selection.IsHover() )
781
782 m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
783 m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
784
787
788 m_frame->OnModify();
789 }
790
791 return 0;
792}
793
794
796{
798
799 if( selection.GetSize() == 0 )
800 return 0;
801
802 bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
803 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
804 bool connections = false;
805 bool moving = item->IsMoving();
806
807 if( selection.GetSize() == 1 )
808 {
809 if( !moving )
811
812 switch( item->Type() )
813 {
814 case SCH_SYMBOL_T:
815 {
816 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
817
818 if( vertical )
819 symbol->SetOrientation( SYM_MIRROR_X );
820 else
821 symbol->SetOrientation( SYM_MIRROR_Y );
822
823 symbol->ClearFieldsAutoplaced();
824 break;
825 }
826
827 case SCH_TEXT_T:
828 case SCH_LABEL_T:
830 case SCH_HIER_LABEL_T:
832 {
833 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
834 textItem->MirrorSpinStyle( !vertical );
835 break;
836 }
837
838 case SCH_SHEET_PIN_T:
839 {
840 // mirror within parent sheet
841 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
842 SCH_SHEET* sheet = pin->GetParent();
843
844 if( vertical )
845 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
846 else
847 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
848
849 break;
850 }
851
852 case SCH_FIELD_T:
853 {
854 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
855
856 if( vertical )
857 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
858 else
859 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
860
861 // Now that we're re-justifying a field, they're no longer autoplaced.
862 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
863
864 break;
865 }
866
867 case SCH_BITMAP_T:
868 if( vertical )
869 item->MirrorVertically( item->GetPosition().y );
870 else
871 item->MirrorHorizontally( item->GetPosition().x );
872
873 // The bitmap is cached in Opengl: clear the cache to redraw
875 break;
876
877 case SCH_SHEET_T:
878 {
879 // Mirror the sheet on itself. Sheets do not have a anchor point.
881
882 if( vertical )
883 item->MirrorVertically( mirrorPoint.y );
884 else
885 item->MirrorHorizontally( mirrorPoint.x );
886
887 break;
888 }
889
890 default:
891 if( vertical )
892 item->MirrorVertically( item->GetPosition().y );
893 else
894 item->MirrorHorizontally( item->GetPosition().x );
895
896 break;
897 }
898
899 connections = item->IsConnectable();
900 m_frame->UpdateItem( item, false, true );
901 }
902 else if( selection.GetSize() > 1 )
903 {
904 VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
905
906 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
907 {
908 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
909
910 if( !moving )
911 saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
912
913 if( item->Type() == SCH_SHEET_PIN_T )
914 {
915 if( item->GetParent()->IsSelected() )
916 {
917 // parent will mirror us
918 }
919 else
920 {
921 // mirror within parent sheet
922 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
923 SCH_SHEET* sheet = pin->GetParent();
924
925 if( vertical )
926 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
927 else
928 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
929 }
930 }
931 else if( item->Type() == SCH_FIELD_T )
932 {
933 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
934
935 if( vertical )
936 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
937 else
938 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
939
940 // Now that we're re-justifying a field, they're no longer autoplaced.
941 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
942 }
943 else
944 {
945 if( vertical )
946 item->MirrorVertically( mirrorPoint.y );
947 else
948 item->MirrorHorizontally( mirrorPoint.x );
949 }
950
951 connections |= item->IsConnectable();
952 m_frame->UpdateItem( item, false, true );
953 }
954 }
955
957
958 // Update R-Tree for modified items
959 for( EDA_ITEM* selected : selection )
960 updateItem( selected, true );
961
962 if( item->IsMoving() )
963 {
965 }
966 else
967 {
968 if( selection.IsHover() )
970
971 if( connections )
973
974 m_frame->OnModify();
975 }
976
977 return 0;
978}
979
980
981const std::vector<KICAD_T> swappableItems = {
995};
996
997
998int SCH_EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
999{
1001 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
1002
1003 if( selection.Size() < 2 )
1004 return 0;
1005
1006 bool isMoving = selection.Front()->IsMoving();
1007 bool appendUndo = isMoving;
1008 bool connections = false;
1009
1010 SCH_SCREEN* screen = this->m_frame->GetScreen();
1011
1012 for( size_t i = 0; i < sorted.size() - 1; i++ )
1013 {
1014 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
1015 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
1016
1017 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
1018 std::swap( aPos, bPos );
1019
1020 saveCopyInUndoList( a, UNDO_REDO::CHANGED, appendUndo );
1021 appendUndo = true;
1022 saveCopyInUndoList( b, UNDO_REDO::CHANGED, appendUndo );
1023
1024 a->SetPosition( aPos );
1025 b->SetPosition( bPos );
1026
1027 if( a->Type() == b->Type() )
1028 {
1029 switch( a->Type() )
1030 {
1031 case SCH_LABEL_T:
1032 case SCH_GLOBAL_LABEL_T:
1033 case SCH_HIER_LABEL_T:
1035 m_frame->AutoRotateItem( screen, a );
1036 m_frame->AutoRotateItem( screen, b );
1037 break;
1038 case SCH_SYMBOL_T:
1039 {
1040 SCH_SYMBOL* aSymbol = static_cast<SCH_SYMBOL*>( a );
1041 SCH_SYMBOL* bSymbol = static_cast<SCH_SYMBOL*>( b );
1042 int aOrient = aSymbol->GetOrientation(), bOrient = bSymbol->GetOrientation();
1043 std::swap( aOrient, bOrient );
1044 aSymbol->SetOrientation( aOrient );
1045 bSymbol->SetOrientation( bOrient );
1046 break;
1047 }
1048 default: break;
1049 }
1050 }
1051
1052 connections |= a->IsConnectable();
1053 connections |= b->IsConnectable();
1054 m_frame->UpdateItem( a, false, true );
1055 m_frame->UpdateItem( b, false, true );
1056 }
1057
1059
1060 // Update R-Tree for modified items
1061 for( EDA_ITEM* selected : selection )
1062 updateItem( selected, true );
1063
1064 if( isMoving )
1065 {
1067 }
1068 else
1069 {
1070 if( selection.IsHover() )
1072
1073 if( connections )
1075
1076 m_frame->OnModify();
1077 }
1078
1079 return 0;
1080}
1081
1082
1084{
1085 const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
1086
1087 if( sourceItems.empty() )
1088 return 0;
1089
1091
1092 bool appendUndo = false;
1093 EE_SELECTION newItems;
1094
1095 for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
1096 {
1097 SCH_ITEM* newItem = item->Duplicate();
1098 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
1099
1100 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
1101 {
1102 // If incrementing tries to go below zero, tell user why the value is repeated
1103
1104 if( !label->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
1105 m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
1106 }
1107
1108 // If cloning a symbol then put into 'move' mode.
1109 if( newItem->Type() == SCH_SYMBOL_T )
1110 {
1111 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
1112 newItem->Move( cursorPos - newItem->GetPosition() );
1113 }
1114 else
1115 {
1118 }
1119
1120 m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem );
1121 newItem->SetFlags( IS_NEW );
1122 m_frame->AddToScreen( newItem, m_frame->GetScreen() );
1123 m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, appendUndo );
1124 appendUndo = true;
1125
1126 if( newItem->Type() == SCH_SYMBOL_T )
1127 {
1129 SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
1130 int annotateStartNum = projSettings.m_AnnotateStartNum;
1131
1132 if( annotate.automatic )
1133 {
1134 static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
1135 NULL_REPORTER reporter;
1137 (ANNOTATE_ALGO_T) annotate.method, annotate.recursive,
1138 annotateStartNum, false, false, reporter, appendUndo );
1139 }
1140
1142 }
1143
1144 newItems.Add( newItem );
1145
1146 newItem->ClearFlags();
1147 }
1148
1149 if( !newItems.Empty() )
1150 {
1153
1156 }
1157
1159 m_frame->OnModify();
1160
1161 if( !newItems.Empty() )
1162 m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
1163
1164 for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
1165 m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
1166
1167 return 0;
1168}
1169
1170
1171static std::vector<KICAD_T> deletableItems =
1172{
1175 SCH_LINE_T,
1179 SCH_TEXT_T,
1189 SCH_FIELD_T, // Will be hidden
1191};
1192
1193
1195{
1196 SCH_SCREEN* screen = m_frame->GetScreen();
1198 bool appendToUndo = false;
1199 std::vector<VECTOR2I> pts;
1200
1201 if( items.empty() )
1202 return 0;
1203
1204 // Don't leave a freed pointer in the selection
1206
1207 for( EDA_ITEM* item : items )
1208 item->ClearFlags( STRUCT_DELETED );
1209
1210 for( EDA_ITEM* item : items )
1211 {
1212 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1213
1214 if( !sch_item )
1215 continue;
1216
1217 if( sch_item->IsConnectable() )
1218 {
1219 std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
1220 pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1221 }
1222
1223 if( sch_item->Type() == SCH_JUNCTION_T )
1224 {
1225 sch_item->SetFlags( STRUCT_DELETED );
1226 // clean up junctions at the end
1227 }
1228 else if( sch_item->Type() == SCH_SHEET_PIN_T )
1229 {
1230 SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1231 SCH_SHEET* sheet = pin->GetParent();
1232
1233 if( !alg::contains( items, sheet ) )
1234 {
1235 pin->SetFlags( STRUCT_DELETED );
1236 saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1237 appendToUndo = true;
1238
1239 updateItem( pin, false );
1240
1241 sheet->RemovePin( pin );
1242 }
1243 }
1244 else if( sch_item->Type() == SCH_FIELD_T )
1245 {
1246 saveCopyInUndoList( item, UNDO_REDO::CHANGED, appendToUndo );
1247 static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
1248 appendToUndo = true;
1249
1250 updateItem( sch_item, false );
1251 }
1252 else
1253 {
1254 sch_item->SetFlags( STRUCT_DELETED );
1255 saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1256 appendToUndo = true;
1257
1258 updateItem( sch_item, false );
1259
1260 m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
1261
1262 if( sch_item->Type() == SCH_SHEET_T )
1264 }
1265 }
1266
1267 for( const VECTOR2I& point : pts )
1268 {
1269 SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1270
1271 if( !junction )
1272 continue;
1273
1274 if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1275 m_frame->DeleteJunction( junction, appendToUndo );
1276 }
1277
1279
1281 m_frame->OnModify();
1282
1283 return 0;
1284}
1285
1286
1287#define HITTEST_THRESHOLD_PIXELS 5
1288
1289
1291{
1293
1295 m_pickerItem = nullptr;
1296
1297 // Deactivate other tools; particularly important if another PICKER is currently running
1298 Activate();
1299
1300 picker->SetCursor( KICURSOR::REMOVE );
1301 picker->SetSnapping( false );
1302
1303 picker->SetClickHandler(
1304 [this]( const VECTOR2D& aPosition ) -> bool
1305 {
1306 if( m_pickerItem )
1307 {
1309 selectionTool->UnbrightenItem( m_pickerItem );
1310 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1312 m_pickerItem = nullptr;
1313 }
1314
1315 return true;
1316 } );
1317
1318 picker->SetMotionHandler(
1319 [this]( const VECTOR2D& aPos )
1320 {
1321 EE_COLLECTOR collector;
1322 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1323 collector.Collect( m_frame->GetScreen(), deletableItems, aPos );
1324
1326 selectionTool->GuessSelectionCandidates( collector, aPos );
1327
1328 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1329
1330 if( m_pickerItem != item )
1331 {
1332 if( m_pickerItem )
1333 selectionTool->UnbrightenItem( m_pickerItem );
1334
1335 m_pickerItem = item;
1336
1337 if( m_pickerItem )
1338 selectionTool->BrightenItem( m_pickerItem );
1339 }
1340 } );
1341
1342 picker->SetFinalizeHandler(
1343 [this]( const int& aFinalState )
1344 {
1345 if( m_pickerItem )
1346 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
1347
1348 // Wake the selection tool after exiting to ensure the cursor gets updated
1350 } );
1351
1353
1354 return 0;
1355}
1356
1357
1359{
1360 // Save old symbol in undo list if not already in edit, or moving.
1361 if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1363
1364 KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1365 wxString caption;
1366
1367 // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1368 if( parentType == SCH_SYMBOL_T && aField->GetId() < MANDATORY_FIELDS )
1369 {
1370 wxString translated_fieldname;
1371 translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(), DO_TRANSLATE );
1372 caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
1373 }
1374 else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
1375 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1376 else
1377 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1378
1379 DIALOG_SCH_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1380
1381 // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1382 if( dlg.ShowQuasiModal() != wxID_OK )
1383 return;
1384
1385 dlg.UpdateField( aField, &m_frame->GetCurrentSheet() );
1386
1387 if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1388 static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1389
1390 m_frame->UpdateItem( aField, false, true );
1391 m_frame->OnModify();
1392
1393 // This must go after OnModify() so that the connectivity graph will have been updated.
1395}
1396
1397
1399{
1400 EE_SELECTION sel;
1401
1402 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1404 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1406 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1408
1409 if( sel.Size() != 1 )
1410 return 0;
1411
1412 bool clearSelection = sel.IsHover();
1413 EDA_ITEM* item = sel.Front();
1414
1415 if( item->Type() == SCH_SYMBOL_T )
1416 {
1417 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1418
1419 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1421 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1422 editFieldText( symbol->GetField( VALUE_FIELD ) );
1423 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1425 }
1426 else if( item->Type() == SCH_FIELD_T )
1427 {
1428 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1429
1430 editFieldText( field );
1431
1432 if( !field->IsVisible() )
1433 clearSelection = true;
1434 }
1435
1436 if( clearSelection )
1438
1439 return 0;
1440}
1441
1442
1444{
1446 SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1447 bool moving = head && head->IsMoving();
1448
1449 if( selection.Empty() )
1450 return 0;
1451
1452 std::vector<SCH_ITEM*> autoplaceItems;
1453
1454 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1455 {
1456 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1457
1458 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
1459 autoplaceItems.push_back( item );
1460 else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
1461 autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
1462 }
1463
1464 bool appendUndo = false;
1465
1466 for( SCH_ITEM* sch_item : autoplaceItems )
1467 {
1468 if( !moving && !sch_item->IsNew() )
1469 {
1470 saveCopyInUndoList( sch_item, UNDO_REDO::CHANGED, appendUndo, false );
1471 appendUndo = true;
1472 }
1473
1474 sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1475
1476 updateItem( sch_item, true );
1477 }
1478
1480
1481 if( moving )
1482 {
1484 }
1485 else
1486 {
1487 if( selection.IsHover() )
1489
1490 m_frame->OnModify();
1491 }
1492
1493 return 0;
1494}
1495
1496
1498{
1499 SCH_SYMBOL* selectedSymbol = nullptr;
1501
1502 if( !selection.Empty() )
1503 selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1504
1506
1507 if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1508 || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1509 {
1511 }
1512
1513 DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1514
1515 dlg.ShowQuasiModal();
1516
1517 return 0;
1518}
1519
1520
1522{
1524
1525 if( selection.Empty() )
1526 return 0;
1527
1528 SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1529
1531 && symbol->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1532 {
1533 return 0;
1534 }
1535
1537 && symbol->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
1538 {
1539 return 0;
1540 }
1541
1542 if( !symbol->IsNew() )
1544
1545 m_frame->ConvertPart( symbol );
1546
1547 if( symbol->IsNew() )
1549
1550 if( selection.IsHover() )
1552
1553 return 0;
1554}
1555
1556
1558{
1560 bool clearSelection = selection.IsHover();
1561
1562 if( selection.Empty() )
1563 {
1564 if( getView()->IsLayerVisible( LAYER_SCHEMATIC_DRAWINGSHEET ) )
1565 {
1567 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1568
1569 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1571 }
1572
1573 return 0;
1574 }
1575
1576 EDA_ITEM* curr_item = selection.Front();
1577
1578 switch( curr_item->Type() )
1579 {
1580 case SCH_LINE_T:
1582 case SCH_JUNCTION_T:
1583 break;
1584
1585 default:
1586 if( selection.Size() > 1 )
1587 return 0;
1588
1589 break;
1590 }
1591
1592 switch( curr_item->Type() )
1593 {
1594 case SCH_SYMBOL_T:
1595 {
1596 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( curr_item );
1597 DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1598
1599 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1600 // frame. Therefore this dialog as a modal frame parent, MUST be run under
1601 // quasimodal mode for the quasimodal frame support to work. So don't use
1602 // the QUASIMODAL macros here.
1603 int retval = symbolPropsDialog.ShowQuasiModal();
1604
1605 if( retval == SYMBOL_PROPS_EDIT_OK )
1606 {
1609
1611 m_frame->OnModify();
1612 }
1613 else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1614 {
1616 true );
1617
1618 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1619 blocking_win->Close( true );
1620
1621 // The broken library symbol link indicator cannot be edited.
1622 if( symbol->IsMissingLibSymbol() )
1623 return 0;
1624
1625 editor->LoadSymbolFromSchematic( symbol );
1626
1627 editor->Show( true );
1628 editor->Raise();
1629 }
1630 else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1631 {
1633 true );
1634
1635 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1636 blocking_win->Close( true );
1637
1638 editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
1639
1640 editor->Show( true );
1641 editor->Raise();
1642 }
1643 else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1644 {
1646 dlg.ShowQuasiModal();
1647 }
1648 else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1649 {
1651 dlg.ShowQuasiModal();
1652 }
1653 }
1654 break;
1655
1656 case SCH_SHEET_T:
1657 {
1658 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( curr_item );
1659 bool doClearAnnotation;
1660 bool doRefresh = false;
1661
1662 // Keep track of existing sheet paths. EditSheet() can modify this list.
1663 // Note that we use the validity checking/repairing version here just to make sure
1664 // we've got a valid hierarchy to begin with.
1665 SCH_SHEET_LIST initial_sheetpathList( &m_frame->Schematic().Root(), true );
1666
1667 doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1668 &doClearAnnotation );
1669
1670 // If the sheet file is changed and new sheet contents are loaded then we have to
1671 // clear the annotations on the new content (as it may have been set from some other
1672 // sheet path reference)
1673 if( doClearAnnotation )
1674 {
1675 SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1676 // We clear annotation of new sheet paths here:
1677 screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
1678 // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1679 // path, but symbols managed by its sheet path must have their annotation cleared
1680 // because they are new:
1681 sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet(), false );
1682 }
1683
1684 if( doRefresh )
1685 {
1689 }
1690
1691 break;
1692 }
1693
1694 case SCH_SHEET_PIN_T:
1695 {
1696 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( curr_item );
1698
1699 // QuasiModal required for help dialog
1700 if( dlg.ShowQuasiModal() == wxID_OK )
1701 {
1703 m_frame->OnModify();
1704 }
1705 }
1706 break;
1707
1708 case SCH_TEXT_T:
1709 case SCH_TEXTBOX_T:
1710 {
1711 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
1712
1713 // Must be quasi modal for syntax help
1714 if( dlg.ShowQuasiModal() == wxID_OK )
1715 {
1717 m_frame->OnModify();
1718 }
1719 }
1720 break;
1721
1722 case SCH_LABEL_T:
1723 case SCH_GLOBAL_LABEL_T:
1724 case SCH_HIER_LABEL_T:
1726 {
1727 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( curr_item ) );
1728
1729 // Must be quasi modal for syntax help
1730 if( dlg.ShowQuasiModal() == wxID_OK )
1731 {
1733 m_frame->OnModify();
1734 }
1735 }
1736 break;
1737
1738 case SCH_FIELD_T:
1739 {
1740 SCH_FIELD* field = static_cast<SCH_FIELD*>( curr_item );
1741
1742 editFieldText( field );
1743
1744 if( !field->IsVisible() )
1745 clearSelection = true;
1746 }
1747 break;
1748
1749 case SCH_SHAPE_T:
1750 {
1751 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
1752
1753 if( dlg.ShowModal() == wxID_OK )
1754 {
1756 m_frame->OnModify();
1757 }
1758 }
1759 break;
1760
1761 case SCH_BITMAP_T:
1762 {
1763 SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( curr_item );
1764 DIALOG_IMAGE_PROPERTIES dlg( m_frame, bitmap );
1765
1766 if( dlg.ShowModal() == wxID_OK )
1767 {
1768 // The bitmap is cached in Opengl: clear the cache in case it has become invalid
1771 m_frame->OnModify();
1772 }
1773 }
1774 break;
1775
1776 case SCH_LINE_T:
1778 case SCH_JUNCTION_T:
1779 if( std::all_of( selection.Items().begin(), selection.Items().end(),
1780 [&]( const EDA_ITEM* item )
1781 {
1782 return item->Type() == SCH_LINE_T
1783 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
1784 } ) )
1785 {
1786 std::deque<SCH_LINE*> lines;
1787
1788 for( EDA_ITEM* selItem : selection.Items() )
1789 lines.push_back( static_cast<SCH_LINE*>( selItem ) );
1790
1791 DIALOG_LINE_PROPERTIES dlg( m_frame, lines );
1792
1793 if( dlg.ShowModal() == wxID_OK )
1794 {
1796 m_frame->OnModify();
1797 }
1798 }
1799 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
1800 [&]( const EDA_ITEM* item )
1801 {
1802 return item->Type() == SCH_JUNCTION_T;
1803 } ) )
1804 {
1805 std::deque<SCH_JUNCTION*> junctions;
1806
1807 for( EDA_ITEM* selItem : selection.Items() )
1808 junctions.push_back( static_cast<SCH_JUNCTION*>( selItem ) );
1809
1810 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1811
1812 if( dlg.ShowModal() == wxID_OK )
1813 {
1815 m_frame->OnModify();
1816 }
1817 }
1818 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
1819 [&]( const EDA_ITEM* item )
1820 {
1821 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
1822
1823 wxCHECK( schItem, false );
1824
1825 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
1826 || item->Type() == SCH_JUNCTION_T;
1827 } ) )
1828 {
1829 std::deque<SCH_ITEM*> items;
1830
1831 for( EDA_ITEM* selItem : selection.Items() )
1832 items.push_back( static_cast<SCH_ITEM*>( selItem ) );
1833
1834 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, items );
1835
1836 if( dlg.ShowModal() == wxID_OK )
1837 {
1839 m_frame->OnModify();
1840 }
1841 }
1842 else
1843 {
1844 return 0;
1845 }
1846
1847 break;
1848
1849 case SCH_MARKER_T: // These items have no properties to edit
1850 case SCH_NO_CONNECT_T:
1851 break;
1852
1853 default: // Unexpected item
1854 wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + curr_item->GetClass() );
1855 }
1856
1857 updateItem( curr_item, true );
1858
1859 if( clearSelection )
1861
1862 return 0;
1863}
1864
1865
1867{
1868 KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
1870 SCH_TEXT_T,
1871 SCH_TEXTBOX_T } );
1872
1873 for( unsigned int i = 0; i < selection.GetSize(); ++i )
1874 {
1875 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( selection.GetItem( i ) );
1876
1877 if( item && item->Type() != convertTo )
1878 {
1879 bool selected = item->IsSelected();
1880 SCH_ITEM* newtext = nullptr;
1881 VECTOR2I position = item->GetPosition();
1882 wxString txt;
1883 wxString href;
1884 TEXT_SPIN_STYLE orientation = TEXT_SPIN_STYLE::SPIN::RIGHT;
1886
1887 switch( item->Type() )
1888 {
1889 case SCH_LABEL_T:
1890 case SCH_GLOBAL_LABEL_T:
1891 case SCH_HIER_LABEL_T:
1892 {
1893 SCH_TEXT* label = static_cast<SCH_LABEL_BASE*>( item );
1894
1895 txt = UnescapeString( label->GetText() );
1896 orientation = label->GetTextSpinStyle();
1897 shape = label->GetShape();
1898 href = label->GetHyperlink();
1899 break;
1900 }
1901
1903 {
1904 SCH_DIRECTIVE_LABEL* dirlabel = static_cast<SCH_DIRECTIVE_LABEL*>( item );
1905
1906 // a SCH_DIRECTIVE_LABEL has no text
1907 txt = _( "<empty>" );
1908
1909 orientation = dirlabel->GetTextSpinStyle();
1910 href = dirlabel->GetHyperlink();
1911 break;
1912 }
1913
1914 case SCH_TEXT_T:
1915 {
1916 SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
1917
1918 txt = text->GetText();
1919 orientation = text->GetTextSpinStyle();
1920 href = text->GetHyperlink();
1921 break;
1922 }
1923
1924 case SCH_TEXTBOX_T:
1925 {
1926 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
1927 BOX2I bbox = textbox->GetBoundingBox();
1928
1929 bbox.Inflate( -textbox->GetTextMargin() );
1930
1931 if( convertTo == SCH_LABEL_T
1932 || convertTo == SCH_HIER_LABEL_T
1933 || convertTo == SCH_GLOBAL_LABEL_T )
1934 {
1935 int textSize = dynamic_cast<EDA_TEXT*>( item )->GetTextSize().y;
1936 bbox.Inflate( item->Schematic()->Settings().m_LabelSizeRatio * textSize );
1937 }
1938
1939 txt = textbox->GetText();
1940
1941 if( textbox->GetTextAngle().IsVertical() )
1942 {
1943 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1944 {
1945 orientation = TEXT_SPIN_STYLE::SPIN::BOTTOM;
1946 position = VECTOR2I( bbox.Centre().x, bbox.GetOrigin().y );
1947 }
1948 else
1949 {
1950 orientation = TEXT_SPIN_STYLE::SPIN::UP;
1951 position = VECTOR2I( bbox.Centre().x, bbox.GetEnd().y );
1952 }
1953 }
1954 else
1955 {
1956 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1957 {
1958 orientation = TEXT_SPIN_STYLE::SPIN::LEFT;
1959 position = VECTOR2I( bbox.GetEnd().x, bbox.Centre().y );
1960 }
1961 else
1962 {
1963 orientation = TEXT_SPIN_STYLE::SPIN::RIGHT;
1964 position = VECTOR2I( bbox.GetOrigin().x, bbox.Centre().y );
1965 }
1966 }
1967
1968 position = m_frame->GetNearestGridPosition( position );
1969 href = textbox->GetHyperlink();
1970 break;
1971 }
1972
1973 default:
1974 UNIMPLEMENTED_FOR( item->GetClass() );
1975 break;
1976 }
1977
1978 auto getValidNetname =
1979 []( const wxString& aText )
1980 {
1981 wxString local_txt = aText;
1982 local_txt.Replace( "\n", "_" );
1983 local_txt.Replace( "\r", "_" );
1984 local_txt.Replace( "\t", "_" );
1985
1986 // Bus groups can have spaces; bus vectors and signal names cannot
1987 if( !NET_SETTINGS::ParseBusGroup( aText, nullptr, nullptr ) )
1988 local_txt.Replace( " ", "_" );
1989
1990 // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
1991 local_txt = EscapeString( local_txt, CTX_NETNAME );
1992
1993 if( local_txt.IsEmpty() )
1994 return _( "<empty>" );
1995 else
1996 return local_txt;
1997 };
1998
1999 switch( convertTo )
2000 {
2001 case SCH_LABEL_T:
2002 {
2003 SCH_LABEL_BASE* new_label = new SCH_LABEL( position, getValidNetname( txt ) );
2004
2005 new_label->SetShape( shape );
2006 new_label->SetTextSpinStyle( orientation );
2007 new_label->SetHyperlink( href );
2008 newtext = new_label;
2009 break;
2010 }
2011
2012 case SCH_GLOBAL_LABEL_T:
2013 {
2014 SCH_LABEL_BASE* new_label = new SCH_GLOBALLABEL( position, getValidNetname( txt ) );
2015
2016 new_label->SetShape( shape );
2017 new_label->SetTextSpinStyle( orientation );
2018 new_label->SetHyperlink( href );
2019 newtext = new_label;
2020 break;
2021 }
2022
2023 case SCH_HIER_LABEL_T:
2024 {
2025 SCH_LABEL_BASE* new_label = new SCH_HIERLABEL( position, getValidNetname( txt ) );
2026
2027 new_label->SetShape( shape );
2028 new_label->SetTextSpinStyle( orientation );
2029 new_label->SetHyperlink( href );
2030 newtext = new_label;
2031 break;
2032 }
2033
2035 {
2036 SCH_LABEL_BASE* new_label = new SCH_DIRECTIVE_LABEL( position );
2037
2038 // A SCH_DIRECTIVE_LABEL usually has at least one field containing the net class
2039 // name. If we're copying from a text object assume the text is the netclass
2040 // name. Otherwise, we'll just copy the fields which will either have a netclass
2041 // or not.
2042 if( !dynamic_cast<SCH_LABEL_BASE*>( item ) )
2043 {
2044 SCH_FIELD netclass( position, 0, new_label, wxT( "Netclass" ) );
2045 netclass.SetText( txt );
2046 netclass.SetVisible( true );
2047 new_label->GetFields().push_back( netclass );
2048 }
2049
2050 new_label->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
2051 new_label->SetTextSpinStyle( orientation );
2052 new_label->SetHyperlink( href );
2053 newtext = new_label;
2054 break;
2055 }
2056
2057 case SCH_TEXT_T:
2058 {
2059 SCH_TEXT* new_text = new SCH_TEXT( position, txt );
2060
2061 new_text->SetTextSpinStyle( orientation );
2062 new_text->SetHyperlink( href );
2063 newtext = new_text;
2064 break;
2065 }
2066
2067 case SCH_TEXTBOX_T:
2068 {
2069 SCH_TEXTBOX* new_textbox = new SCH_TEXTBOX( 0, FILL_T::NO_FILL, txt );
2070 BOX2I bbox = item->GetBoundingBox();
2071
2072 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
2073 bbox.Inflate( -label->GetLabelBoxExpansion() );
2074
2075 // Careful: GetTextMargin() is dependent on font size...
2076 new_textbox->SetTextSize( dynamic_cast<EDA_TEXT*>( item )->GetTextSize() );
2077
2078 int margin = new_textbox->GetTextMargin();
2079 bbox.Inflate( margin );
2080
2081 // Add 1/20 of the margin at the end to reduce line-breaking changes.
2082 int slop = margin / 20;
2083
2084 switch( orientation )
2085 {
2086 case TEXT_SPIN_STYLE::SPIN::RIGHT:
2087 new_textbox->SetPosition( bbox.GetPosition() );
2088 new_textbox->SetEnd( bbox.GetEnd() + VECTOR2I( slop, 0 ) );
2089 break;
2090
2091 case TEXT_SPIN_STYLE::SPIN::LEFT:
2092 new_textbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2093 new_textbox->SetPosition( bbox.GetPosition() - VECTOR2I( slop, 0 ) );
2094 new_textbox->SetEnd( bbox.GetEnd() );
2095 break;
2096
2097 case TEXT_SPIN_STYLE::SPIN::UP:
2098 new_textbox->SetTextAngle( ANGLE_VERTICAL );
2099 new_textbox->SetPosition( bbox.GetPosition() - VECTOR2I( 0, slop ) );
2100 new_textbox->SetEnd( bbox.GetEnd() );
2101 break;
2102
2103 case TEXT_SPIN_STYLE::SPIN::BOTTOM:
2104 new_textbox->SetTextAngle( ANGLE_VERTICAL );
2105 new_textbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2106 new_textbox->SetPosition( bbox.GetPosition() );
2107 new_textbox->SetEnd( bbox.GetEnd() + VECTOR2I( 0, slop ) );
2108 break;
2109 }
2110
2111 new_textbox->SetHyperlink( href );
2112 newtext = new_textbox;
2113 break;
2114 }
2115
2116 default:
2117 UNIMPLEMENTED_FOR( wxString::Format( "%d.", convertTo ) );
2118 break;
2119 }
2120
2121 wxCHECK2( newtext, continue );
2122
2123 // Copy the old text item settings to the new one. Justifications are not copied
2124 // because they are not used in labels. Justifications will be set to default value
2125 // in the new text item type.
2126 //
2127 newtext->SetFlags( item->GetEditFlags() );
2128
2129 EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( item );
2130 EDA_TEXT* new_eda_text = dynamic_cast<EDA_TEXT*>( newtext );
2131
2132 new_eda_text->SetTextSize( eda_text->GetTextSize() );
2133 new_eda_text->SetTextThickness( eda_text->GetTextThickness() );
2134 new_eda_text->SetItalic( eda_text->IsItalic() );
2135 new_eda_text->SetBold( eda_text->IsBold() );
2136
2137 newtext->AutoplaceFields( m_frame->GetScreen(), false );
2138
2139 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item );
2140 SCH_LABEL_BASE* new_label = dynamic_cast<SCH_LABEL_BASE*>( newtext );
2141
2142 if( label && new_label )
2143 new_label->SetFields( label->GetFields() );
2144
2145 if( selected )
2147
2148 if( !item->IsNew() )
2149 {
2150 saveCopyInUndoList( item, UNDO_REDO::DELETED, i != 0 );
2151 saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
2152
2154 m_frame->AddToScreen( newtext, m_frame->GetScreen() );
2155 }
2156
2157 if( selected )
2158 m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
2159
2160 // Otherwise, pointer is owned by the undo stack
2161 if( item->IsNew() )
2162 delete item;
2163
2164 if( convertTo == SCH_TEXT_T || convertTo == SCH_TEXTBOX_T )
2165 {
2166 if( newtext->IsDangling() )
2167 getView()->Update( newtext, KIGFX::REPAINT );
2168 }
2169 else
2170 {
2172 }
2173
2174 m_frame->OnModify();
2175 }
2176 }
2177
2178 if( selection.IsHover() )
2180
2181 return 0;
2182}
2183
2184
2186{
2189
2190 std::vector<SCH_LINE*> lines;
2191
2192 for( EDA_ITEM* item : selection )
2193 {
2194 if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
2195 {
2196 if( !line->IsEndPoint( cursorPos ) )
2197 lines.push_back( line );
2198 }
2199 }
2200
2203
2204 for( SCH_LINE* line : lines )
2205 {
2206 m_frame->BreakSegment( line, cursorPos );
2207
2208 VECTOR2I v = line->GetEndPoint() - line->GetStartPoint();
2209 v = v.Resize( v.EuclideanNorm() - 10 );
2210 line->SetEndPoint( line->GetStartPoint() + v );
2211 }
2212
2213 if( !lines.empty() )
2214 {
2216
2217 m_frame->OnModify();
2219
2221 }
2222
2223 return 0;
2224}
2225
2226
2228{
2230 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2231
2232 if( !sheet || !sheet->HasUndefinedPins() )
2233 return 0;
2234
2235 if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
2236 return 0;
2237
2239
2240 sheet->CleanupSheet();
2241
2242 updateItem( sheet, true );
2243 m_frame->OnModify();
2244
2245 if( selection.IsHover() )
2247
2248 return 0;
2249}
2250
2251
2253{
2255
2256 if( selection.GetSize() > 1 )
2257 return 0;
2258
2259 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2260
2262
2263 SCH_SCREEN* screen;
2264
2265 if( sheet )
2266 {
2267 // When changing the page number of a selected sheet, the current screen owns the sheet.
2268 screen = m_frame->GetScreen();
2269
2270 instance.push_back( sheet );
2271 }
2272 else
2273 {
2274 SCH_SHEET_PATH prevInstance = instance;
2275
2276 // When change the page number in the screen, the previous screen owns the sheet.
2277 if( prevInstance.size() )
2278 {
2279 prevInstance.pop_back();
2280 screen = prevInstance.LastScreen();
2281 }
2282 else
2283 {
2284 // The root sheet and root screen are effectively the same thing.
2285 screen = m_frame->GetScreen();
2286 }
2287
2288 sheet = m_frame->GetCurrentSheet().Last();
2289 }
2290
2291 wxString msg;
2292 wxString sheetPath = instance.PathHumanReadable( false );
2293 wxString pageNumber = instance.GetPageNumber();
2294
2295 msg.Printf( _( "Enter page number for sheet path%s" ),
2296 ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
2297
2298 wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
2299
2300 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
2301
2302 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
2303 return 0;
2304
2305 m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
2306
2307 instance.SetPageNumber( dlg.GetValue() );
2308
2309 if( instance == m_frame->GetCurrentSheet() )
2310 {
2311 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
2313 }
2314
2315 m_frame->OnModify();
2316
2317 return 0;
2318}
2319
2320
2322{
2323 wxString aFileName = *aEvent.Parameter<wxString*>();
2324 return ( m_frame->AddSheetAndUpdateDisplay( aFileName ) ? 0 : 1 );
2325}
2326
2327
2329{
2335 Go( &SCH_EDIT_TOOL::Swap, EE_ACTIONS::swap.MakeEvent() );
2338
2357
2360
2364
2366}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
@ component_select_unit
static TOOL_ACTION paste
Definition: actions.h:69
static TOOL_ACTION copy
Definition: actions.h:68
static TOOL_ACTION pickerTool
Definition: actions.h:158
static TOOL_ACTION pasteSpecial
Definition: actions.h:70
static TOOL_ACTION pageSettings
Definition: actions.h:56
static TOOL_ACTION duplicate
Definition: actions.h:72
static TOOL_ACTION doDelete
Definition: actions.h:73
static TOOL_ACTION deleteTool
Definition: actions.h:74
static TOOL_ACTION cut
Definition: actions.h:67
static TOOL_ACTION refreshPreview
Definition: actions.h:109
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:87
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:73
void SetPageNumber(const wxString &aPageNumber)
Definition: base_screen.h:79
const Vec & GetPosition() const
Definition: box2.h:184
const Vec & GetOrigin() const
Definition: box2.h:183
const Vec GetCenter() const
Definition: box2.h:195
const Vec GetEnd() const
Definition: box2.h:185
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
Vec Centre() const
Definition: box2.h:70
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
int m_Threshold
Definition: collector.h:234
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_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
Update the board display after modifying it by a python script (note: it is automatically called by a...
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:249
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:250
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:147
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
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:143
bool IsSelected() const
Definition: eda_item.h:107
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:183
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:145
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:145
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
bool IsItalic() const
Definition: eda_text.h:120
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:117
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
virtual bool IsVisible() const
Definition: eda_text.h:126
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:248
wxString GetHyperlink() const
Definition: eda_text.h:325
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:139
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetBold(bool aBold)
Definition: eda_text.cpp:209
bool IsBold() const
Definition: eda_text.h:123
void SetHyperlink(wxString aLink)
Definition: eda_text.h:326
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:142
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
int GetTextThickness() const
Definition: eda_text.h:109
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
VECTOR2I GetTextSize() const
Definition: eda_text.h:186
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
PANEL_ANNOTATE m_AnnotatePanel
AUTOPLACE_FIELDS m_AutoplaceFields
static TOOL_ACTION mirrorV
Definition: ee_actions.h:128
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
static TOOL_ACTION properties
Definition: ee_actions.h:131
static TOOL_ACTION move
Definition: ee_actions.h:123
static TOOL_ACTION clearHighlight
Definition: ee_actions.h:253
static TOOL_ACTION toGLabel
Definition: ee_actions.h:143
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:212
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION drag
Definition: ee_actions.h:124
static TOOL_ACTION toText
Definition: ee_actions.h:144
static TOOL_ACTION placeClassLabel
Definition: ee_actions.h:90
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:138
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:135
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:137
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:127
static TOOL_ACTION editValue
Definition: ee_actions.h:133
static TOOL_ACTION toLabel
Definition: ee_actions.h:140
static TOOL_ACTION toTextBox
Definition: ee_actions.h:145
static TOOL_ACTION breakWire
Definition: ee_actions.h:146
static TOOL_ACTION mirrorH
Definition: ee_actions.h:129
static TOOL_ACTION rotateCW
Definition: ee_actions.h:126
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:173
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:91
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:60
static TOOL_ACTION ddAppendFile
Definition: ee_actions.h:258
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:92
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
static TOOL_ACTION trimOverlappingWires
Definition: ee_actions.h:79
static TOOL_ACTION editPageNumber
Definition: ee_actions.h:166
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:161
static TOOL_ACTION editFootprint
Definition: ee_actions.h:134
static TOOL_ACTION enterSheet
Definition: ee_actions.h:201
static TOOL_ACTION editReference
Definition: ee_actions.h:132
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:160
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:96
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:159
static TOOL_ACTION addNeededJunctions
Definition: ee_actions.h:78
static TOOL_ACTION toCLabel
Definition: ee_actions.h:141
static TOOL_ACTION placeLabel
Definition: ee_actions.h:89
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:125
static TOOL_ACTION toHLabel
Definition: ee_actions.h:142
static TOOL_ACTION editTextAndGraphics
Definition: ee_actions.h:213
static TOOL_ACTION swap
Definition: ee_actions.h:130
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:136
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:162
static TOOL_ACTION breakBus
Definition: ee_actions.h:147
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 SingleSymbolOrPower
static SELECTION_CONDITION SingleMultiUnitSymbol
static SELECTION_CONDITION SingleDeMorganSymbol
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:50
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:103
void saveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aType, bool aAppend=false, bool aDirtyConnectivity=true)
Definition: ee_tool_base.h:134
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:184
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:66
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:210
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:100
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1574
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1381
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
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:394
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:588
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:82
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:71
void SetSnapping(bool aSnap)
Definition: picker_tool.h:64
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:62
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:102
These settings were stored in SCH_BASE_FRAME previously.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:172
SCH_SHEET & Root() const
Definition: schematic.h:90
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,...
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Add an item to 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
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:275
void DeleteJunction(SCH_ITEM *aItem, bool aAppend=false)
Removes a given junction and heals any wire segments under the junction.
const SCH_CONNECTION * GetHighlightedConnection() const
bool BreakSegment(SCH_LINE *aSegment, const VECTOR2I &aPoint, SCH_LINE **aNewSegment=nullptr, SCH_SCREEN *aScreen=nullptr)
Break a single segment into two at the specified point.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
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.
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 RecalculateConnections(SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
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:461
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 StartNewUndo()
Create a new, blank stack for future Undo commands to be pushed to.
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
void AnnotateSymbols(ANNOTATE_SCOPE_T aAnnotateScope, ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption, bool aRecursive, int aStartNumber, bool aResetAnnotation, bool aRepairTimestamps, REPORTER &aReporter, bool appendUndo=false)
Annotate the symbols in the schematic that are not currently annotated.
Definition: annotate.cpp:194
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
int DeleteItemCursor(const TOOL_EVENT &aEvent)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
EDA_ITEM * m_pickerItem
Definition: sch_edit_tool.h:91
int EditField(const TOOL_EVENT &aEvent)
int EditPageNumber(const TOOL_EVENT &aEvent)
int DoDelete(const TOOL_EVENT &aEvent)
Run the deletion tool.
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 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 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 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:50
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:721
int GetId() const
Definition: sch_field.h:116
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:811
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
virtual bool IsConnectable() const
Definition: sch_item.h:340
virtual void MirrorVertically(int aCenter)=0
Mirror item vertically about aCenter.
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:157
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:112
virtual bool IsDangling() const
Definition: sch_item.h:333
virtual void MirrorHorizontally(int aCenter)=0
Mirror item horizontally about aCenter.
void ClearFieldsAutoplaced()
Definition: sch_item.h:418
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:246
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:433
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:427
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:446
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:355
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:93
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:162
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_label.h:98
void SetShape(LABEL_FLAG_SHAPE aShape) override
Definition: sch_label.h:74
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:90
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:396
void RotateStart(const VECTOR2I &aCenter)
Definition: sch_line.cpp:390
VECTOR2I GetEndPoint() const
Definition: sch_line.h:137
VECTOR2I GetStartPoint() const
Definition: sch_line.h:132
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:613
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:427
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
SCH_ITEM * GetItem(const VECTOR2I &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:335
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...
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
wxString PathHumanReadable(bool aUseShortRootName=true) const
Return the sheet path in a human readable form made from the sheet names.
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 symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_sheet.cpp:808
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:677
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:539
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:363
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:425
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:645
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:666
Schematic symbol object.
Definition: sch_symbol.h:79
int GetUnit() const
Definition: sch_symbol.h:225
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:776
int GetConvert() const
Definition: sch_symbol.h:267
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:242
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
int GetOrientation() const
Get the display symbol orientation.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:172
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:189
int GetTextMargin() const
Definition: sch_textbox.cpp:64
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:170
TEXT_SPIN_STYLE GetTextSpinStyle() const
Definition: sch_text.h:148
virtual LABEL_FLAG_SHAPE GetShape() const
Definition: sch_text.h:150
virtual void SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:188
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:179
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
void BrightenItem(EDA_ITEM *aItem)
int AddItemToSel(const TOOL_EVENT &aEvent)
void UnbrightenItem(EDA_ITEM *aItem)
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:65
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:118
const std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:202
VECTOR2I GetReferencePoint() const
Definition: selection.h:244
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:83
bool IsHover() const
Definition: selection.h:81
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:97
EDA_ITEM * Front() const
Definition: selection.h:200
int Size() const
Returns the number of selected parts.
Definition: selection.h:113
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:205
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:107
bool HasReferencePoint() const
Definition: selection.h:239
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:214
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:156
bool DisableGridSnapping() const
Definition: tool_event.h:344
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition: tool_event.h:365
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:88
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.
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
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
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:378
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:342
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:408
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:409
#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.
@ ID_POPUP_SCH_SELECT_UNIT1
Definition: eeschema_id.h:95
@ ID_POPUP_SCH_SELECT_UNIT_CMP
Definition: eeschema_id.h:94
@ ID_POPUP_SCH_SELECT_UNIT_SYM_MAX
Definition: eeschema_id.h:98
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ LAYER_WIRE
Definition: layer_ids.h:344
@ LAYER_BUS
Definition: layer_ids.h:345
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:382
#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:120
@ REPAINT
Item needs to be redrawn.
Definition: view_item.h:52
wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
Definition: ui_common.cpp:70
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ LOCAL_CLEANUP
@ SYM_MIRROR_Y
@ SYM_MIRROR_X
#define HITTEST_THRESHOLD_PIXELS
static std::vector< KICAD_T > deletableItems
const std::vector< KICAD_T > swappableItems
const std::vector< KICAD_T > rotatableItems
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:47
LABEL_FLAG_SHAPE
Definition: sch_text.h:96
@ L_UNSPECIFIED
Definition: sch_text.h:101
@ F_ROUND
Definition: sch_text.h:105
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
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:54
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 4 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:145
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:142
@ SCH_FIELD_LOCATE_REFERENCE_T
Definition: typeinfo.h:163
@ SCH_FIELD_LOCATE_FOOTPRINT_T
Definition: typeinfo.h:165
@ SCH_SYMBOL_T
Definition: typeinfo.h:155
@ SCH_FIELD_T
Definition: typeinfo.h:154
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:153
@ SCH_LABEL_T
Definition: typeinfo.h:150
@ SCH_FIELD_LOCATE_VALUE_T
Definition: typeinfo.h:164
@ SCH_SHEET_T
Definition: typeinfo.h:157
@ SCH_MARKER_T
Definition: typeinfo.h:140
@ SCH_SHAPE_T
Definition: typeinfo.h:146
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:152
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:144
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:174
@ SCHEMATIC_T
Definition: typeinfo.h:187
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:156
@ SCH_TEXT_T
Definition: typeinfo.h:149
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:143
@ SCH_BITMAP_T
Definition: typeinfo.h:147
@ SCH_TEXTBOX_T
Definition: typeinfo.h:148
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:151
@ SCH_JUNCTION_T
Definition: typeinfo.h:141
@ SCH_PIN_T
Definition: typeinfo.h:158
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:80
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618