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 {
197 return false;
198
200 };
201
202 auto propertiesCondition =
203 [&]( const SELECTION& aSel )
204 {
205 if( aSel.GetSize() == 0 )
206 {
208 {
211
212 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
213 return true;
214 }
215
216 return false;
217 }
218
219 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
220 const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
221
222 if( !firstItem || !eeSelection )
223 return false;
224
225 switch( firstItem->Type() )
226 {
227 case SCH_SYMBOL_T:
228 case SCH_SHEET_T:
229 case SCH_SHEET_PIN_T:
230 case SCH_TEXT_T:
231 case SCH_TEXTBOX_T:
232 case SCH_LABEL_T:
234 case SCH_HIER_LABEL_T:
236 case SCH_FIELD_T:
237 case SCH_SHAPE_T:
238 case SCH_BITMAP_T:
239 return aSel.GetSize() == 1;
240
241 case SCH_LINE_T:
243 case SCH_JUNCTION_T:
244 if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
245 [&]( const EDA_ITEM* item )
246 {
247 return item->Type() == SCH_LINE_T
248 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
249 } ) )
250 {
251 return true;
252 }
253 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
254 [&]( const EDA_ITEM* item )
255 {
256 return item->Type() == SCH_JUNCTION_T;
257 } ) )
258 {
259 return true;
260 }
261 else if( std::all_of( aSel.Items().begin(), aSel.Items().end(),
262 [&]( const EDA_ITEM* item )
263 {
264 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
265
266 wxCHECK( schItem, false );
267
268 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
269 || item->Type() == SCH_JUNCTION_T;
270 } ) )
271 {
272 return true;
273 }
274
275 return false;
276
277 default:
278 return false;
279 }
280 };
281
282 auto autoplaceCondition =
283 []( const SELECTION& aSel )
284 {
285 for( const EDA_ITEM* item : aSel )
286 {
287 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
288 return true;
289 }
290
291 return false;
292 };
293
294 // allTextTypes does not include SCH_SHEET_PIN_T because one cannot convert other
295 // types to/from this type, living only in a SHEET
296 static std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
302
303 auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
304
305 auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_DIRECTIVE_LABEL_T,
309 SCH_TEXTBOX_T } ) )
310 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
311
312 auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
316 SCH_TEXTBOX_T } ) )
317 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
318
319 auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
323 SCH_TEXTBOX_T } ) )
324 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
325
326 auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
330 SCH_TEXTBOX_T } ) )
331 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
332
333 auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
337 SCH_TEXTBOX_T } ) )
338 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
339
340 auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
344 SCH_TEXT_T } ) )
345 || ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
346
347 auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_BUS_WIRE_ENTRY_T,
349
350 auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
351
352 //
353 // Add edit actions to the move tool menu
354 //
355 if( moveTool )
356 {
357 CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
358
359 moveMenu.AddSeparator();
360 moveMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition );
361 moveMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition );
362 moveMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition );
363 moveMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition );
365
366 moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
367
368 CONDITIONAL_MENU* editMoveItemSubMenu = new CONDITIONAL_MENU(moveTool);
369 editMoveItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
370 editMoveItemSubMenu->SetIcon( BITMAPS::right );
371 moveMenu.AddMenu( editMoveItemSubMenu, E_C::SingleSymbol );
372
373 editMoveItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol );
374 editMoveItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol );
375 editMoveItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol );
376
378
379 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
380 symUnitMenu->SetTool( this );
381 m_menu.RegisterSubMenu( symUnitMenu );
382 moveMenu.AddMenu( symUnitMenu.get(), E_C::SingleMultiUnitSymbol, 1 );
383
384 moveMenu.AddSeparator();
388 moveMenu.AddItem( ACTIONS::duplicate, duplicateCondition );
389 }
390
391 //
392 // Add editing actions to the drawing tool menu
393 //
394 CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
395
396 drawMenu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
397 drawMenu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
398
399 drawMenu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
400 drawMenu.AddSeparator( sheetSelection && EE_CONDITIONS::Idle, 1 );
401
402 drawMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
403 drawMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
404 drawMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
405 drawMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
406
407 drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
408
409 CONDITIONAL_MENU* editDrawItemSubMenu = new CONDITIONAL_MENU( drawingTools );
410 editDrawItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
411 editDrawItemSubMenu->SetIcon( BITMAPS::right );
412 drawMenu.AddMenu( editDrawItemSubMenu, E_C::SingleSymbol, 200 );
413
414 editDrawItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
415 editDrawItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
416 editDrawItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
417
419
420 drawMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
421
422 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
423 symUnitMenu2->SetTool( drawingTools );
424 drawingTools->GetToolMenu().RegisterSubMenu( symUnitMenu2 );
425 drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
426
428
429 drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
430 drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
431 drawMenu.AddItem( EE_ACTIONS::toGLabel, anyTextTool && E_C::Idle, 200 );
432 drawMenu.AddItem( EE_ACTIONS::toText, anyTextTool && E_C::Idle, 200 );
433 drawMenu.AddItem( EE_ACTIONS::toTextBox, anyTextTool && E_C::Idle, 200 );
434
435 //
436 // Add editing actions to the selection tool menu
437 //
439
440 selToolMenu.AddItem( EE_ACTIONS::rotateCCW, orientCondition, 200 );
441 selToolMenu.AddItem( EE_ACTIONS::rotateCW, orientCondition, 200 );
442 selToolMenu.AddItem( EE_ACTIONS::mirrorV, orientCondition, 200 );
443 selToolMenu.AddItem( EE_ACTIONS::mirrorH, orientCondition, 200 );
445
446 selToolMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
447
448 CONDITIONAL_MENU* editSelItemSubMenu = new CONDITIONAL_MENU( moveTool );
449 editSelItemSubMenu->SetTitle( _( "Edit Main Fields" ) );
450 editSelItemSubMenu->SetIcon( BITMAPS::right );
451 selToolMenu.AddMenu( editSelItemSubMenu, E_C::SingleSymbol, 200 );
452
453 editSelItemSubMenu->AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
454 editSelItemSubMenu->AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
455 editSelItemSubMenu->AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
456
457 selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, autoplaceCondition, 200 );
459
460 std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
461 symUnitMenu3->SetTool( m_selectionTool );
463 selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
464
470
471 CONDITIONAL_MENU* convertToSubMenu = new CONDITIONAL_MENU( m_selectionTool );
472 convertToSubMenu->SetTitle( _( "Change To" ) );
473 convertToSubMenu->SetIcon( BITMAPS::right );
474 selToolMenu.AddMenu( convertToSubMenu, toChangeCondition, 200 );
475
476 convertToSubMenu->AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 );
477 convertToSubMenu->AddItem( EE_ACTIONS::toCLabel, toCLabelCondition, 200 );
478 convertToSubMenu->AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 );
479 convertToSubMenu->AddItem( EE_ACTIONS::toGLabel, toGLabelCondition, 200 );
480 convertToSubMenu->AddItem( EE_ACTIONS::toText, toTextCondition, 200 );
481 convertToSubMenu->AddItem( EE_ACTIONS::toTextBox, toTextBoxCondition, 200 );
482
483 selToolMenu.AddItem( EE_ACTIONS::cleanupSheetPins, sheetHasUndefinedPins, 250 );
484
485 selToolMenu.AddSeparator( 300 );
486 selToolMenu.AddItem( ACTIONS::cut, E_C::IdleSelection, 300 );
487 selToolMenu.AddItem( ACTIONS::copy, E_C::IdleSelection, 300 );
488 selToolMenu.AddItem( ACTIONS::paste, E_C::Idle, 300 );
489 selToolMenu.AddItem( ACTIONS::pasteSpecial, E_C::Idle, 300 );
490 selToolMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty, 300 );
491 selToolMenu.AddItem( ACTIONS::duplicate, duplicateCondition, 300 );
492
493 selToolMenu.AddSeparator( 400 );
494 selToolMenu.AddItem( ACTIONS::selectAll, hasElements, 400 );
495
496
497 return true;
498}
499
500
501const std::vector<KICAD_T> SCH_EDIT_TOOL::RotatableItems = {
519};
520
521
523{
524 bool clockwise = ( aEvent.Matches( EE_ACTIONS::rotateCW.MakeEvent() ) );
526
527 if( selection.GetSize() == 0 )
528 return 0;
529
530 SCH_ITEM* head = nullptr;
531 int principalItemCount = 0; // User-selected items (as opposed to connected wires)
532 VECTOR2I rotPoint;
533 bool moving = false;
534
535 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
536 {
537 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
538
539 if( item->HasFlag( SELECTED_BY_DRAG ) )
540 continue;
541
542 principalItemCount++;
543
544 if( !head )
545 head = item;
546 }
547
548 if( head && head->IsMoving() )
549 moving = true;
550
551 if( principalItemCount == 1 )
552 {
553 if( moving && selection.HasReferencePoint() )
554 rotPoint = selection.GetReferencePoint();
555 else if( head->IsConnectable() )
556 rotPoint = head->GetPosition();
557 else
559
560 if( !moving )
562
563 switch( head->Type() )
564 {
565 case SCH_SYMBOL_T:
566 {
567 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( head );
568
569 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
570 symbol->Rotate( rotPoint );
571
574
575 break;
576 }
577
578 case SCH_TEXT_T:
579 case SCH_LABEL_T:
581 case SCH_HIER_LABEL_T:
583 {
584 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( head );
585 textItem->Rotate90( clockwise );
586 break;
587 }
588
589 case SCH_SHEET_PIN_T:
590 {
591 // Rotate pin within parent sheet
592 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( head );
593 SCH_SHEET* sheet = pin->GetParent();
594
595 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
596 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
597
598 break;
599 }
600
601 case SCH_LINE_T:
602 {
603 SCH_LINE* line = static_cast<SCH_LINE*>( head );
604
605 // Equal checks for both and neither. We need this because on undo
606 // the item will have both flags cleared, but will be selected, so it is possible
607 // for the user to get a selected line with neither endpoint selected. We
608 // set flags to make sure Rotate() works when we call it.
609 if( line->HasFlag( STARTPOINT ) == line->HasFlag( ENDPOINT ) )
610 {
611 line->SetFlags( STARTPOINT | ENDPOINT );
612
613 // When we allow off grid items, the rotPoint should be set to the midpoint
614 // of the line to allow rotation around the center, and the next if
615 // should become an else-if
616 }
617
618 if( line->HasFlag( STARTPOINT ) )
619 rotPoint = line->GetEndPoint();
620 else if( line->HasFlag( ENDPOINT ) )
621 rotPoint = line->GetStartPoint();
622 }
623
625 case SCH_JUNCTION_T:
628 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
629 head->Rotate( rotPoint );
630
631 break;
632
633 case SCH_FIELD_T:
634 {
635 SCH_FIELD* field = static_cast<SCH_FIELD*>( head );
636
637 if( field->GetTextAngle().IsHorizontal() )
639 else
641
642 // Now that we're moving a field, they're no longer autoplaced.
643 static_cast<SCH_ITEM*>( head->GetParent() )->ClearFieldsAutoplaced();
644
645 break;
646 }
647
648 case SCH_SHAPE_T:
649 case SCH_TEXTBOX_T:
650 for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
651 head->Rotate( rotPoint );
652
653 break;
654
655 case SCH_BITMAP_T:
656 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
657 head->Rotate( rotPoint );
658
659 // The bitmap is cached in Opengl: clear the cache to redraw
661 break;
662
663 case SCH_SHEET_T:
664 {
665 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( head );
667
668 // Rotate the sheet on itself. Sheets do not have an anchor point.
669 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
670 sheet->Rotate( rotPoint );
671
672 break;
673 }
674
675 default:
676 UNIMPLEMENTED_FOR( head->GetClass() );
677 }
678
679 m_frame->UpdateItem( head, false, true );
680 }
681 else
682 {
683 if( moving && selection.HasReferencePoint() )
684 rotPoint = selection.GetReferencePoint();
685 else
686 rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
687 }
688
689 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
690 {
691 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
692
693 // We've already rotated the user selected item if there was only one. We're just
694 // here to rotate the ends of wires that were attached to it.
695 if( principalItemCount == 1 && !item->HasFlag( SELECTED_BY_DRAG ) )
696 continue;
697
698 if( !moving )
699 saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
700
701 for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
702 {
703 if( item->Type() == SCH_LINE_T )
704 {
705 SCH_LINE* line = (SCH_LINE*) item;
706
707 // If we are rotating more than one item, we do not have start/end
708 // points separately selected
709 if( item->HasFlag( STARTPOINT ) )
710 line->RotateStart( rotPoint );
711
712 if( item->HasFlag( ENDPOINT ) )
713 line->RotateEnd( rotPoint );
714 }
715 else if( item->Type() == SCH_SHEET_PIN_T )
716 {
717 if( item->GetParent()->IsSelected() )
718 {
719 // parent will rotate us
720 }
721 else
722 {
723 // rotate within parent
724 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
725 SCH_SHEET* sheet = pin->GetParent();
726
727 pin->Rotate( sheet->GetBodyBoundingBox().GetCenter() );
728 }
729 }
730 else if( item->Type() == SCH_FIELD_T )
731 {
732 if( item->GetParent()->IsSelected() )
733 {
734 // parent will rotate us
735 }
736 else
737 {
738 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
739
740 field->Rotate( rotPoint );
741
742 if( field->GetTextAngle().IsHorizontal() )
744 else
746
747 // Now that we're moving a field, they're no longer autoplaced.
748 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
749 }
750 }
751 else
752 {
753 item->Rotate( rotPoint );
754 }
755 }
756
757 m_frame->UpdateItem( item, false, true );
758 updateItem( item, true );
759 }
760
762
763 if( moving )
764 {
766 }
767 else
768 {
769 EE_SELECTION selectionCopy = selection;
770
771 if( selection.IsHover() )
773
775 lwbTool->TrimOverLappingWires( &selectionCopy );
776 lwbTool->AddJunctionsIfNeeded( &selectionCopy );
777
780
781 m_frame->OnModify();
782 }
783
784 return 0;
785}
786
787
789{
791
792 if( selection.GetSize() == 0 )
793 return 0;
794
795 bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
796 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
797 bool connections = false;
798 bool moving = item->IsMoving();
799
800 if( selection.GetSize() == 1 )
801 {
802 if( !moving )
804
805 switch( item->Type() )
806 {
807 case SCH_SYMBOL_T:
808 {
809 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
810
811 if( vertical )
812 symbol->SetOrientation( SYM_MIRROR_X );
813 else
814 symbol->SetOrientation( SYM_MIRROR_Y );
815
816 symbol->ClearFieldsAutoplaced();
817 break;
818 }
819
820 case SCH_TEXT_T:
821 case SCH_LABEL_T:
823 case SCH_HIER_LABEL_T:
825 {
826 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( item );
827 textItem->MirrorSpinStyle( !vertical );
828 break;
829 }
830
831 case SCH_SHEET_PIN_T:
832 {
833 // mirror within parent sheet
834 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
835 SCH_SHEET* sheet = pin->GetParent();
836
837 if( vertical )
838 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
839 else
840 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
841
842 break;
843 }
844
845 case SCH_FIELD_T:
846 {
847 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
848
849 if( vertical )
850 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
851 else
852 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
853
854 // Now that we're re-justifying a field, they're no longer autoplaced.
855 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
856
857 break;
858 }
859
860 case SCH_BITMAP_T:
861 if( vertical )
862 item->MirrorVertically( item->GetPosition().y );
863 else
864 item->MirrorHorizontally( item->GetPosition().x );
865
866 // The bitmap is cached in Opengl: clear the cache to redraw
868 break;
869
870 case SCH_SHEET_T:
871 {
872 // Mirror the sheet on itself. Sheets do not have a anchor point.
874
875 if( vertical )
876 item->MirrorVertically( mirrorPoint.y );
877 else
878 item->MirrorHorizontally( mirrorPoint.x );
879
880 break;
881 }
882
883 default:
884 if( vertical )
885 item->MirrorVertically( item->GetPosition().y );
886 else
887 item->MirrorHorizontally( item->GetPosition().x );
888
889 break;
890 }
891
892 connections = item->IsConnectable();
893 m_frame->UpdateItem( item, false, true );
894 }
895 else if( selection.GetSize() > 1 )
896 {
897 VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
898
899 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
900 {
901 item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
902
903 if( !moving )
904 saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
905
906 if( item->Type() == SCH_SHEET_PIN_T )
907 {
908 if( item->GetParent()->IsSelected() )
909 {
910 // parent will mirror us
911 }
912 else
913 {
914 // mirror within parent sheet
915 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( item );
916 SCH_SHEET* sheet = pin->GetParent();
917
918 if( vertical )
919 pin->MirrorVertically( sheet->GetBoundingBox().GetCenter().y );
920 else
921 pin->MirrorHorizontally( sheet->GetBoundingBox().GetCenter().x );
922 }
923 }
924 else if( item->Type() == SCH_FIELD_T )
925 {
926 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
927
928 if( vertical )
929 field->SetVertJustify( TO_VJUSTIFY( -field->GetVertJustify() ) );
930 else
931 field->SetHorizJustify( TO_HJUSTIFY( -field->GetHorizJustify() ) );
932
933 // Now that we're re-justifying a field, they're no longer autoplaced.
934 static_cast<SCH_ITEM*>( field->GetParent() )->ClearFieldsAutoplaced();
935 }
936 else
937 {
938 if( vertical )
939 item->MirrorVertically( mirrorPoint.y );
940 else
941 item->MirrorHorizontally( mirrorPoint.x );
942 }
943
944 connections |= item->IsConnectable();
945 m_frame->UpdateItem( item, false, true );
946 }
947 }
948
950
951 // Update R-Tree for modified items
952 for( EDA_ITEM* selected : selection )
953 updateItem( selected, true );
954
955 if( item->IsMoving() )
956 {
958 }
959 else
960 {
961 EE_SELECTION selectionCopy = selection;
962
963 if( selection.IsHover() )
965
966 if( connections )
967 {
969 lwbTool->TrimOverLappingWires( &selectionCopy );
970 lwbTool->AddJunctionsIfNeeded( &selectionCopy );
971
974 }
975
976 m_frame->OnModify();
977 }
978
979 return 0;
980}
981
982
983const std::vector<KICAD_T> swappableItems = {
997};
998
999
1001{
1003 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
1004
1005 if( selection.Size() < 2 )
1006 return 0;
1007
1008 bool isMoving = selection.Front()->IsMoving();
1009 bool appendUndo = isMoving;
1010 bool connections = false;
1011
1012 SCH_SCREEN* screen = this->m_frame->GetScreen();
1013
1014 for( size_t i = 0; i < sorted.size() - 1; i++ )
1015 {
1016 SCH_ITEM* a = static_cast<SCH_ITEM*>( sorted[i] );
1017 SCH_ITEM* b = static_cast<SCH_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
1018
1019 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
1020 std::swap( aPos, bPos );
1021
1022 saveCopyInUndoList( a, UNDO_REDO::CHANGED, appendUndo );
1023 appendUndo = true;
1024 saveCopyInUndoList( b, UNDO_REDO::CHANGED, appendUndo );
1025
1026 a->SetPosition( aPos );
1027 b->SetPosition( bPos );
1028
1029 if( a->Type() == b->Type() )
1030 {
1031 switch( a->Type() )
1032 {
1033 case SCH_LABEL_T:
1034 case SCH_GLOBAL_LABEL_T:
1035 case SCH_HIER_LABEL_T:
1037 m_frame->AutoRotateItem( screen, a );
1038 m_frame->AutoRotateItem( screen, b );
1039 break;
1040 case SCH_SYMBOL_T:
1041 {
1042 SCH_SYMBOL* aSymbol = static_cast<SCH_SYMBOL*>( a );
1043 SCH_SYMBOL* bSymbol = static_cast<SCH_SYMBOL*>( b );
1044 int aOrient = aSymbol->GetOrientation(), bOrient = bSymbol->GetOrientation();
1045 std::swap( aOrient, bOrient );
1046 aSymbol->SetOrientation( aOrient );
1047 bSymbol->SetOrientation( bOrient );
1048 break;
1049 }
1050 default: break;
1051 }
1052 }
1053
1054 connections |= a->IsConnectable();
1055 connections |= b->IsConnectable();
1056 m_frame->UpdateItem( a, false, true );
1057 m_frame->UpdateItem( b, false, true );
1058 }
1059
1061
1062 // Update R-Tree for modified items
1063 for( EDA_ITEM* selected : selection )
1064 updateItem( selected, true );
1065
1066 if( isMoving )
1067 {
1069 }
1070 else
1071 {
1072 if( selection.IsHover() )
1074
1075 if( connections )
1077
1078 m_frame->OnModify();
1079 }
1080
1081 return 0;
1082}
1083
1084
1086{
1087 const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
1088
1089 if( sourceItems.empty() )
1090 return 0;
1091
1093
1094 bool appendUndo = false;
1095 EE_SELECTION newItems;
1096
1097 for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
1098 {
1099 SCH_ITEM* newItem = item->Duplicate();
1100 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
1101
1102 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
1103 {
1104 // If incrementing tries to go below zero, tell user why the value is repeated
1105
1106 if( !label->IncrementLabel( cfg->m_Drawing.repeat_label_increment ) )
1107 m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
1108 }
1109
1110 // If cloning a symbol then put into 'move' mode.
1111 if( newItem->Type() == SCH_SYMBOL_T )
1112 {
1113 VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
1114 newItem->Move( cursorPos - newItem->GetPosition() );
1115 }
1116 else
1117 {
1120 }
1121
1122 m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem );
1123 newItem->SetFlags( IS_NEW );
1124 m_frame->AddToScreen( newItem, m_frame->GetScreen() );
1125 m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, appendUndo );
1126 appendUndo = true;
1127
1128 if( newItem->Type() == SCH_SYMBOL_T )
1129 {
1131 SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
1132 int annotateStartNum = projSettings.m_AnnotateStartNum;
1133
1134 if( annotate.automatic )
1135 {
1136 static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
1137 NULL_REPORTER reporter;
1139 (ANNOTATE_ORDER_T) annotate.sort_order,
1140 (ANNOTATE_ALGO_T) annotate.method, true /* recursive */,
1141 annotateStartNum, false, false, reporter, appendUndo );
1142 }
1143
1145 }
1146
1147 newItems.Add( newItem );
1148
1149 newItem->ClearFlags();
1150 }
1151
1152 if( !newItems.Empty() )
1153 {
1155 lwbTool->TrimOverLappingWires( &newItems );
1156 lwbTool->AddJunctionsIfNeeded( &newItems );
1157
1160 }
1161
1163 m_frame->OnModify();
1164
1165 if( !newItems.Empty() )
1166 m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
1167
1168 for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
1169 m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
1170
1171 return 0;
1172}
1173
1174
1175static std::vector<KICAD_T> deletableItems =
1176{
1179 SCH_LINE_T,
1183 SCH_TEXT_T,
1193 SCH_FIELD_T, // Will be hidden
1195};
1196
1197
1199{
1200 SCH_SCREEN* screen = m_frame->GetScreen();
1202 bool appendToUndo = false;
1203 std::vector<VECTOR2I> pts;
1204
1205 if( items.empty() )
1206 return 0;
1207
1208 // Don't leave a freed pointer in the selection
1210
1211 for( EDA_ITEM* item : items )
1212 item->ClearFlags( STRUCT_DELETED );
1213
1214 for( EDA_ITEM* item : items )
1215 {
1216 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
1217
1218 if( !sch_item )
1219 continue;
1220
1221 if( sch_item->IsConnectable() )
1222 {
1223 std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
1224 pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
1225 }
1226
1227 if( sch_item->Type() == SCH_JUNCTION_T )
1228 {
1229 sch_item->SetFlags( STRUCT_DELETED );
1230 // clean up junctions at the end
1231 }
1232 else if( sch_item->Type() == SCH_SHEET_PIN_T )
1233 {
1234 SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) sch_item;
1235 SCH_SHEET* sheet = pin->GetParent();
1236
1237 if( !alg::contains( items, sheet ) )
1238 {
1239 pin->SetFlags( STRUCT_DELETED );
1240 saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1241 appendToUndo = true;
1242
1243 updateItem( pin, false );
1244
1245 sheet->RemovePin( pin );
1246 }
1247 }
1248 else if( sch_item->Type() == SCH_FIELD_T )
1249 {
1250 saveCopyInUndoList( item, UNDO_REDO::CHANGED, appendToUndo );
1251 static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
1252 appendToUndo = true;
1253
1254 updateItem( sch_item, false );
1255 }
1256 else
1257 {
1258 sch_item->SetFlags( STRUCT_DELETED );
1259 saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
1260 appendToUndo = true;
1261
1262 updateItem( sch_item, false );
1263
1264 m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
1265
1266 if( sch_item->Type() == SCH_SHEET_T )
1268 }
1269 }
1270
1271 for( const VECTOR2I& point : pts )
1272 {
1273 SCH_ITEM* junction = screen->GetItem( point, 0, SCH_JUNCTION_T );
1274
1275 if( !junction )
1276 continue;
1277
1278 if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
1279 m_frame->DeleteJunction( junction, appendToUndo );
1280 }
1281
1283
1285 m_frame->OnModify();
1286
1287 return 0;
1288}
1289
1290
1291#define HITTEST_THRESHOLD_PIXELS 5
1292
1293
1295{
1297
1299 m_pickerItem = nullptr;
1300
1301 // Deactivate other tools; particularly important if another PICKER is currently running
1302 Activate();
1303
1304 picker->SetCursor( KICURSOR::REMOVE );
1305 picker->SetSnapping( false );
1306
1307 picker->SetClickHandler(
1308 [this]( const VECTOR2D& aPosition ) -> bool
1309 {
1310 if( m_pickerItem )
1311 {
1313 selectionTool->UnbrightenItem( m_pickerItem );
1314 selectionTool->AddItemToSel( m_pickerItem, true /*quiet mode*/ );
1316 m_pickerItem = nullptr;
1317 }
1318
1319 return true;
1320 } );
1321
1322 picker->SetMotionHandler(
1323 [this]( const VECTOR2D& aPos )
1324 {
1325 EE_COLLECTOR collector;
1326 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1327 collector.Collect( m_frame->GetScreen(), deletableItems, aPos );
1328
1330 selectionTool->GuessSelectionCandidates( collector, aPos );
1331
1332 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
1333
1334 if( m_pickerItem != item )
1335 {
1336 if( m_pickerItem )
1337 selectionTool->UnbrightenItem( m_pickerItem );
1338
1339 m_pickerItem = item;
1340
1341 if( m_pickerItem )
1342 selectionTool->BrightenItem( m_pickerItem );
1343 }
1344 } );
1345
1346 picker->SetFinalizeHandler(
1347 [this]( const int& aFinalState )
1348 {
1349 if( m_pickerItem )
1350 m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
1351
1352 // Wake the selection tool after exiting to ensure the cursor gets updated
1354 } );
1355
1357
1358 return 0;
1359}
1360
1361
1363{
1364 // Save old symbol in undo list if not already in edit, or moving.
1365 if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved
1367
1368 KICAD_T parentType = aField->GetParent() ? aField->GetParent()->Type() : SCHEMATIC_T;
1369 wxString caption;
1370
1371 // Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
1372 if( parentType == SCH_SYMBOL_T && aField->GetId() < MANDATORY_FIELDS )
1373 {
1374 wxString translated_fieldname;
1375 translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(),
1376 DO_TRANSLATE );
1377 caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
1378 }
1379 else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
1380 caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
1381 else
1382 caption.Printf( _( "Edit '%s' Field" ), aField->GetName() );
1383
1384 DIALOG_SCH_FIELD_PROPERTIES dlg( m_frame, caption, aField );
1385
1386 // The footprint field dialog can invoke a KIWAY_PLAYER so we must use a quasi-modal
1387 if( dlg.ShowQuasiModal() != wxID_OK )
1388 return;
1389
1390 dlg.UpdateField( aField, &m_frame->GetCurrentSheet() );
1391
1392 if( m_frame->eeconfig()->m_AutoplaceFields.enable || parentType == SCH_SHEET_T )
1393 static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
1394
1395 m_frame->UpdateItem( aField, false, true );
1396 m_frame->OnModify();
1397
1398 // This must go after OnModify() so that the connectivity graph will have been updated.
1400}
1401
1402
1404{
1405 EE_SELECTION sel;
1406
1407 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1409 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1411 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1413
1414 if( sel.Size() != 1 )
1415 return 0;
1416
1417 bool clearSelection = sel.IsHover();
1418 EDA_ITEM* item = sel.Front();
1419
1420 if( item->Type() == SCH_SYMBOL_T )
1421 {
1422 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1423
1424 if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
1426 else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
1427 editFieldText( symbol->GetField( VALUE_FIELD ) );
1428 else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
1430 }
1431 else if( item->Type() == SCH_FIELD_T )
1432 {
1433 SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
1434
1435 editFieldText( field );
1436
1437 if( !field->IsVisible() )
1438 clearSelection = true;
1439 }
1440
1441 if( clearSelection )
1443
1444 return 0;
1445}
1446
1447
1449{
1451 SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
1452 bool moving = head && head->IsMoving();
1453
1454 if( selection.Empty() )
1455 return 0;
1456
1457 std::vector<SCH_ITEM*> autoplaceItems;
1458
1459 for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
1460 {
1461 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
1462
1463 if( item->IsType( EE_COLLECTOR::FieldOwners ) )
1464 autoplaceItems.push_back( item );
1465 else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
1466 autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
1467 }
1468
1469 bool appendUndo = false;
1470
1471 for( SCH_ITEM* sch_item : autoplaceItems )
1472 {
1473 if( !moving && !sch_item->IsNew() )
1474 {
1475 saveCopyInUndoList( sch_item, UNDO_REDO::CHANGED, appendUndo, false );
1476 appendUndo = true;
1477 }
1478
1479 sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
1480
1481 updateItem( sch_item, true );
1482 }
1483
1485
1486 if( moving )
1487 {
1489 }
1490 else
1491 {
1492 if( selection.IsHover() )
1494
1495 m_frame->OnModify();
1496 }
1497
1498 return 0;
1499}
1500
1501
1503{
1504 SCH_SYMBOL* selectedSymbol = nullptr;
1506
1507 if( !selection.Empty() )
1508 selectedSymbol = dynamic_cast<SCH_SYMBOL*>( selection.Front() );
1509
1511
1512 if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
1513 || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
1514 {
1516 }
1517
1518 DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
1519
1520 dlg.ShowQuasiModal();
1521
1522 return 0;
1523}
1524
1525
1527{
1529
1530 if( selection.Empty() )
1531 return 0;
1532
1533 SCH_SYMBOL* symbol = (SCH_SYMBOL*) selection.Front();
1534
1536 && symbol->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
1537 {
1538 return 0;
1539 }
1540
1542 && symbol->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
1543 {
1544 return 0;
1545 }
1546
1547 if( !symbol->IsNew() )
1549
1550 m_frame->ConvertPart( symbol );
1551
1552 if( symbol->IsNew() )
1554
1555 if( selection.IsHover() )
1557
1558 return 0;
1559}
1560
1561
1563{
1565 bool clearSelection = selection.IsHover();
1566
1567 if( selection.Empty() )
1568 {
1569 if( getView()->IsLayerVisible( LAYER_SCHEMATIC_DRAWINGSHEET ) )
1570 {
1572 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1573
1574 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1576 }
1577
1578 return 0;
1579 }
1580
1581 EDA_ITEM* curr_item = selection.Front();
1582
1583 switch( curr_item->Type() )
1584 {
1585 case SCH_LINE_T:
1587 case SCH_JUNCTION_T:
1588 break;
1589
1590 default:
1591 if( selection.Size() > 1 )
1592 return 0;
1593
1594 break;
1595 }
1596
1597 switch( curr_item->Type() )
1598 {
1599 case SCH_SYMBOL_T:
1600 {
1601 int retval;
1602 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( curr_item );
1603
1604 // This needs to be scoped so the dialog destructor removes blocking status
1605 // before we launch the next dialog.
1606 {
1607 DIALOG_SYMBOL_PROPERTIES symbolPropsDialog( m_frame, symbol );
1608
1609 // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
1610 // frame. Therefore this dialog as a modal frame parent, MUST be run under
1611 // quasimodal mode for the quasimodal frame support to work. So don't use
1612 // the QUASIMODAL macros here.
1613 retval = symbolPropsDialog.ShowQuasiModal();
1614 }
1615
1616 if( retval == SYMBOL_PROPS_EDIT_OK )
1617 {
1620
1622 m_frame->OnModify();
1623 }
1624 else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
1625 {
1627 true );
1628
1629 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1630 blocking_win->Close( true );
1631
1632 // The broken library symbol link indicator cannot be edited.
1633 if( symbol->IsMissingLibSymbol() )
1634 return 0;
1635
1636 editor->LoadSymbolFromSchematic( symbol );
1637
1638 editor->Show( true );
1639 editor->Raise();
1640 }
1641 else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
1642 {
1644 true );
1645
1646 if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
1647 blocking_win->Close( true );
1648
1649 editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
1650
1651 editor->Show( true );
1652 editor->Raise();
1653 }
1654 else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
1655 {
1657 dlg.ShowQuasiModal();
1658 }
1659 else if( retval == SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL )
1660 {
1662 dlg.ShowQuasiModal();
1663 }
1664 }
1665 break;
1666
1667 case SCH_SHEET_T:
1668 {
1669 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( curr_item );
1670 bool doClearAnnotation;
1671 bool doRefresh = false;
1672
1673 // Keep track of existing sheet paths. EditSheet() can modify this list.
1674 // Note that we use the validity checking/repairing version here just to make sure
1675 // we've got a valid hierarchy to begin with.
1676 SCH_SHEET_LIST originalHierarchy( &m_frame->Schematic().Root(), true );
1677
1678 doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
1679 &doClearAnnotation );
1680
1681 // If the sheet file is changed and new sheet contents are loaded then we have to
1682 // clear the annotations on the new content (as it may have been set from some other
1683 // sheet path reference)
1684 if( doClearAnnotation )
1685 {
1686 SCH_SCREENS screensList( &m_frame->Schematic().Root() );
1687
1688 // We clear annotation of new sheet paths here:
1689 screensList.ClearAnnotationOfNewSheetPaths( originalHierarchy );
1690
1691 // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new
1692 // path, but symbols managed by its sheet path must have their annotation cleared
1693 // because they are new:
1694 sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet(), false );
1695 }
1696
1697 if( doRefresh )
1698 {
1702 }
1703
1704 break;
1705 }
1706
1707 case SCH_SHEET_PIN_T:
1708 {
1709 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( curr_item );
1711
1712 // QuasiModal required for help dialog
1713 if( dlg.ShowQuasiModal() == wxID_OK )
1714 {
1716 m_frame->OnModify();
1717 }
1718 }
1719 break;
1720
1721 case SCH_TEXT_T:
1722 case SCH_TEXTBOX_T:
1723 {
1724 DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
1725
1726 // Must be quasi modal for syntax help
1727 if( dlg.ShowQuasiModal() == wxID_OK )
1728 {
1730 m_frame->OnModify();
1731 }
1732 }
1733 break;
1734
1735 case SCH_LABEL_T:
1736 case SCH_GLOBAL_LABEL_T:
1737 case SCH_HIER_LABEL_T:
1739 {
1740 DIALOG_LABEL_PROPERTIES dlg( m_frame, static_cast<SCH_LABEL_BASE*>( curr_item ) );
1741
1742 // Must be quasi modal for syntax help
1743 if( dlg.ShowQuasiModal() == wxID_OK )
1744 {
1746 m_frame->OnModify();
1747 }
1748 }
1749 break;
1750
1751 case SCH_FIELD_T:
1752 {
1753 SCH_FIELD* field = static_cast<SCH_FIELD*>( curr_item );
1754
1755 editFieldText( field );
1756
1757 if( !field->IsVisible() )
1758 clearSelection = true;
1759 }
1760 break;
1761
1762 case SCH_SHAPE_T:
1763 {
1764 DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( curr_item ) );
1765
1766 if( dlg.ShowModal() == wxID_OK )
1767 {
1769 m_frame->OnModify();
1770 }
1771 }
1772 break;
1773
1774 case SCH_BITMAP_T:
1775 {
1776 SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( curr_item );
1777 DIALOG_IMAGE_PROPERTIES dlg( m_frame, bitmap );
1778
1779 if( dlg.ShowModal() == wxID_OK )
1780 {
1781 // The bitmap is cached in Opengl: clear the cache in case it has become invalid
1784 m_frame->OnModify();
1785 }
1786 }
1787 break;
1788
1789 case SCH_LINE_T:
1791 case SCH_JUNCTION_T:
1792 if( std::all_of( selection.Items().begin(), selection.Items().end(),
1793 [&]( const EDA_ITEM* item )
1794 {
1795 return item->Type() == SCH_LINE_T
1796 && static_cast<const SCH_LINE*>( item )->IsGraphicLine();
1797 } ) )
1798 {
1799 std::deque<SCH_LINE*> lines;
1800
1801 for( EDA_ITEM* selItem : selection.Items() )
1802 lines.push_back( static_cast<SCH_LINE*>( selItem ) );
1803
1804 DIALOG_LINE_PROPERTIES dlg( m_frame, lines );
1805
1806 if( dlg.ShowModal() == wxID_OK )
1807 {
1809 m_frame->OnModify();
1810 }
1811 }
1812 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
1813 [&]( const EDA_ITEM* item )
1814 {
1815 return item->Type() == SCH_JUNCTION_T;
1816 } ) )
1817 {
1818 std::deque<SCH_JUNCTION*> junctions;
1819
1820 for( EDA_ITEM* selItem : selection.Items() )
1821 junctions.push_back( static_cast<SCH_JUNCTION*>( selItem ) );
1822
1823 DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
1824
1825 if( dlg.ShowModal() == wxID_OK )
1826 {
1828 m_frame->OnModify();
1829 }
1830 }
1831 else if( std::all_of( selection.Items().begin(), selection.Items().end(),
1832 [&]( const EDA_ITEM* item )
1833 {
1834 const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
1835
1836 wxCHECK( schItem, false );
1837
1838 return ( schItem->HasLineStroke() && schItem->IsConnectable() )
1839 || item->Type() == SCH_JUNCTION_T;
1840 } ) )
1841 {
1842 std::deque<SCH_ITEM*> items;
1843
1844 for( EDA_ITEM* selItem : selection.Items() )
1845 items.push_back( static_cast<SCH_ITEM*>( selItem ) );
1846
1847 DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, items );
1848
1849 if( dlg.ShowModal() == wxID_OK )
1850 {
1852 m_frame->OnModify();
1853 }
1854 }
1855 else
1856 {
1857 return 0;
1858 }
1859
1860 break;
1861
1862 case SCH_MARKER_T: // These items have no properties to edit
1863 case SCH_NO_CONNECT_T:
1864 break;
1865
1866 default: // Unexpected item
1867 wxFAIL_MSG( wxString( "Cannot edit schematic item type " ) + curr_item->GetClass() );
1868 }
1869
1870 updateItem( curr_item, true );
1871
1872 if( clearSelection )
1874
1875 return 0;
1876}
1877
1878
1880{
1881 KICAD_T convertTo = aEvent.Parameter<KICAD_T>();
1883 SCH_TEXT_T,
1884 SCH_TEXTBOX_T } );
1885
1886 for( unsigned int i = 0; i < selection.GetSize(); ++i )
1887 {
1888 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( selection.GetItem( i ) );
1889
1890 if( item && item->Type() != convertTo )
1891 {
1892 bool selected = item->IsSelected();
1893 SCH_ITEM* newtext = nullptr;
1894 VECTOR2I position = item->GetPosition();
1895 wxString txt;
1896 wxString href;
1897 TEXT_SPIN_STYLE orientation = TEXT_SPIN_STYLE::SPIN::RIGHT;
1899
1900 switch( item->Type() )
1901 {
1902 case SCH_LABEL_T:
1903 case SCH_GLOBAL_LABEL_T:
1904 case SCH_HIER_LABEL_T:
1905 {
1906 SCH_TEXT* label = static_cast<SCH_LABEL_BASE*>( item );
1907
1908 txt = UnescapeString( label->GetText() );
1909 orientation = label->GetTextSpinStyle();
1910 shape = label->GetShape();
1911 href = label->GetHyperlink();
1912 break;
1913 }
1914
1916 {
1917 SCH_DIRECTIVE_LABEL* dirlabel = static_cast<SCH_DIRECTIVE_LABEL*>( item );
1918
1919 // a SCH_DIRECTIVE_LABEL has no text
1920 txt = _( "<empty>" );
1921
1922 orientation = dirlabel->GetTextSpinStyle();
1923 href = dirlabel->GetHyperlink();
1924 break;
1925 }
1926
1927 case SCH_TEXT_T:
1928 {
1929 SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
1930
1931 txt = text->GetText();
1932 orientation = text->GetTextSpinStyle();
1933 href = text->GetHyperlink();
1934 break;
1935 }
1936
1937 case SCH_TEXTBOX_T:
1938 {
1939 SCH_TEXTBOX* textbox = static_cast<SCH_TEXTBOX*>( item );
1940 BOX2I bbox = textbox->GetBoundingBox();
1941
1942 bbox.Inflate( -textbox->GetTextMargin() );
1943
1944 if( convertTo == SCH_LABEL_T
1945 || convertTo == SCH_HIER_LABEL_T
1946 || convertTo == SCH_GLOBAL_LABEL_T )
1947 {
1948 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
1949 wxCHECK( text, 0 );
1950 int textSize = text->GetTextSize().y;
1951 bbox.Inflate( item->Schematic()->Settings().m_LabelSizeRatio * textSize );
1952 }
1953
1954 txt = textbox->GetText();
1955
1956 if( textbox->GetTextAngle().IsVertical() )
1957 {
1958 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1959 {
1960 orientation = TEXT_SPIN_STYLE::SPIN::BOTTOM;
1961 position = VECTOR2I( bbox.Centre().x, bbox.GetOrigin().y );
1962 }
1963 else
1964 {
1965 orientation = TEXT_SPIN_STYLE::SPIN::UP;
1966 position = VECTOR2I( bbox.Centre().x, bbox.GetEnd().y );
1967 }
1968 }
1969 else
1970 {
1971 if( textbox->GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1972 {
1973 orientation = TEXT_SPIN_STYLE::SPIN::LEFT;
1974 position = VECTOR2I( bbox.GetEnd().x, bbox.Centre().y );
1975 }
1976 else
1977 {
1978 orientation = TEXT_SPIN_STYLE::SPIN::RIGHT;
1979 position = VECTOR2I( bbox.GetOrigin().x, bbox.Centre().y );
1980 }
1981 }
1982
1983 position = m_frame->GetNearestGridPosition( position );
1984 href = textbox->GetHyperlink();
1985 break;
1986 }
1987
1988 default:
1989 UNIMPLEMENTED_FOR( item->GetClass() );
1990 break;
1991 }
1992
1993 auto getValidNetname =
1994 []( const wxString& aText )
1995 {
1996 wxString local_txt = aText;
1997 local_txt.Replace( "\n", "_" );
1998 local_txt.Replace( "\r", "_" );
1999 local_txt.Replace( "\t", "_" );
2000
2001 // Bus groups can have spaces; bus vectors and signal names cannot
2002 if( !NET_SETTINGS::ParseBusGroup( aText, nullptr, nullptr ) )
2003 local_txt.Replace( " ", "_" );
2004
2005 // label strings are "escaped" i.e. a '/' is replaced by "{slash}"
2006 local_txt = EscapeString( local_txt, CTX_NETNAME );
2007
2008 if( local_txt.IsEmpty() )
2009 return _( "<empty>" );
2010 else
2011 return local_txt;
2012 };
2013
2014 switch( convertTo )
2015 {
2016 case SCH_LABEL_T:
2017 {
2018 SCH_LABEL_BASE* new_label = new SCH_LABEL( position, getValidNetname( txt ) );
2019
2020 new_label->SetShape( shape );
2021 new_label->SetTextSpinStyle( orientation );
2022 new_label->SetHyperlink( href );
2023 newtext = new_label;
2024 break;
2025 }
2026
2027 case SCH_GLOBAL_LABEL_T:
2028 {
2029 SCH_LABEL_BASE* new_label = new SCH_GLOBALLABEL( position, getValidNetname( txt ) );
2030
2031 new_label->SetShape( shape );
2032 new_label->SetTextSpinStyle( orientation );
2033 new_label->SetHyperlink( href );
2034 newtext = new_label;
2035 break;
2036 }
2037
2038 case SCH_HIER_LABEL_T:
2039 {
2040 SCH_LABEL_BASE* new_label = new SCH_HIERLABEL( position, getValidNetname( txt ) );
2041
2042 new_label->SetShape( shape );
2043 new_label->SetTextSpinStyle( orientation );
2044 new_label->SetHyperlink( href );
2045 newtext = new_label;
2046 break;
2047 }
2048
2050 {
2051 SCH_LABEL_BASE* new_label = new SCH_DIRECTIVE_LABEL( position );
2052
2053 // A SCH_DIRECTIVE_LABEL usually has at least one field containing the net class
2054 // name. If we're copying from a text object assume the text is the netclass
2055 // name. Otherwise, we'll just copy the fields which will either have a netclass
2056 // or not.
2057 if( !dynamic_cast<SCH_LABEL_BASE*>( item ) )
2058 {
2059 SCH_FIELD netclass( position, 0, new_label, wxT( "Netclass" ) );
2060 netclass.SetText( txt );
2061 netclass.SetVisible( true );
2062 new_label->GetFields().push_back( netclass );
2063 }
2064
2065 new_label->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
2066 new_label->SetTextSpinStyle( orientation );
2067 new_label->SetHyperlink( href );
2068 newtext = new_label;
2069 break;
2070 }
2071
2072 case SCH_TEXT_T:
2073 {
2074 SCH_TEXT* new_text = new SCH_TEXT( position, txt );
2075
2076 new_text->SetTextSpinStyle( orientation );
2077 new_text->SetHyperlink( href );
2078 newtext = new_text;
2079 break;
2080 }
2081
2082 case SCH_TEXTBOX_T:
2083 {
2084 SCH_TEXTBOX* new_textbox = new SCH_TEXTBOX( 0, FILL_T::NO_FILL, txt );
2085 BOX2I bbox = item->GetBoundingBox();
2086
2087 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
2088 bbox.Inflate( -label->GetLabelBoxExpansion() );
2089
2090 EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( item );
2091 wxCHECK(textItem, 0 );
2092
2093 // Careful: GetTextMargin() is dependent on font size...
2094 new_textbox->SetTextSize( textItem->GetTextSize() );
2095
2096 int margin = new_textbox->GetTextMargin();
2097 bbox.Inflate( margin );
2098
2099 // Add 1/20 of the margin at the end to reduce line-breaking changes.
2100 int slop = margin / 20;
2101
2102 switch( orientation )
2103 {
2104 case TEXT_SPIN_STYLE::SPIN::RIGHT:
2105 new_textbox->SetPosition( bbox.GetPosition() );
2106 new_textbox->SetEnd( bbox.GetEnd() + VECTOR2I( slop, 0 ) );
2107 break;
2108
2109 case TEXT_SPIN_STYLE::SPIN::LEFT:
2110 new_textbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2111 new_textbox->SetPosition( bbox.GetPosition() - VECTOR2I( slop, 0 ) );
2112 new_textbox->SetEnd( bbox.GetEnd() );
2113 break;
2114
2115 case TEXT_SPIN_STYLE::SPIN::UP:
2116 new_textbox->SetTextAngle( ANGLE_VERTICAL );
2117 new_textbox->SetPosition( bbox.GetPosition() - VECTOR2I( 0, slop ) );
2118 new_textbox->SetEnd( bbox.GetEnd() );
2119 break;
2120
2121 case TEXT_SPIN_STYLE::SPIN::BOTTOM:
2122 new_textbox->SetTextAngle( ANGLE_VERTICAL );
2123 new_textbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
2124 new_textbox->SetPosition( bbox.GetPosition() );
2125 new_textbox->SetEnd( bbox.GetEnd() + VECTOR2I( 0, slop ) );
2126 break;
2127 }
2128
2129 new_textbox->SetHyperlink( href );
2130 newtext = new_textbox;
2131 break;
2132 }
2133
2134 default:
2135 UNIMPLEMENTED_FOR( wxString::Format( "%d.", convertTo ) );
2136 break;
2137 }
2138
2139 wxCHECK2( newtext, continue );
2140
2141 // Copy the old text item settings to the new one. Justifications are not copied
2142 // because they are not used in labels. Justifications will be set to default value
2143 // in the new text item type.
2144 //
2145 newtext->SetFlags( item->GetEditFlags() );
2146
2147 EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( item );
2148 EDA_TEXT* new_eda_text = dynamic_cast<EDA_TEXT*>( newtext );
2149
2150 wxCHECK2( eda_text && new_eda_text, continue );
2151
2152 new_eda_text->SetFont( eda_text->GetFont() );
2153 new_eda_text->SetTextSize( eda_text->GetTextSize() );
2154 new_eda_text->SetTextThickness( eda_text->GetTextThickness() );
2155 new_eda_text->SetItalic( eda_text->IsItalic() );
2156 new_eda_text->SetBold( eda_text->IsBold() );
2157
2158 newtext->AutoplaceFields( m_frame->GetScreen(), false );
2159
2160 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item );
2161 SCH_LABEL_BASE* new_label = dynamic_cast<SCH_LABEL_BASE*>( newtext );
2162
2163 if( label && new_label )
2164 new_label->SetFields( label->GetFields() );
2165
2166 if( selected )
2168
2169 if( !item->IsNew() )
2170 {
2171 saveCopyInUndoList( item, UNDO_REDO::DELETED, i != 0 );
2172 saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
2173
2175 m_frame->AddToScreen( newtext, m_frame->GetScreen() );
2176 }
2177
2178 if( selected )
2179 m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
2180
2181 // Otherwise, pointer is owned by the undo stack
2182 if( item->IsNew() )
2183 delete item;
2184
2185 if( convertTo == SCH_TEXT_T || convertTo == SCH_TEXTBOX_T )
2186 {
2187 if( newtext->IsDangling() )
2188 getView()->Update( newtext, KIGFX::REPAINT );
2189 }
2190 else
2191 {
2193 }
2194
2195 m_frame->OnModify();
2196 }
2197 }
2198
2199 if( selection.IsHover() )
2201
2202 return 0;
2203}
2204
2205
2207{
2208 bool isSlice = aEvent.Matches( EE_ACTIONS::slice.MakeEvent() );
2211
2212 std::vector<SCH_LINE*> lines;
2213
2214 for( EDA_ITEM* item : selection )
2215 {
2216 if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
2217 {
2218 if( !line->IsEndPoint( cursorPos ) )
2219 lines.push_back( line );
2220 }
2221 }
2222
2225
2226 for( SCH_LINE* line : lines )
2227 {
2228 SCH_LINE* newLine;
2229
2230 // We let the user select the break point if they're on a single line
2231 if( lines.size() == 1 && line->HitTest( cursorPos ) )
2232 m_frame->BreakSegment( line, cursorPos, &newLine );
2233 else
2234 m_frame->BreakSegment( line, line->GetMidPoint(), &newLine );
2235
2236 // Make sure both endpoints are deselected
2237 newLine->ClearFlags();
2238
2240 line->SetFlags( ENDPOINT );
2241
2242 // If we're a break, we want to drag both wires.
2243 // Side note: the drag/move tool only checks whether the first item is
2244 // new to determine if it should append undo or not, someday this should
2245 // be cleaned up and explictly controlled but for now the newLine
2246 // selection addition must be after the existing line.
2247 if( !isSlice )
2248 {
2249 m_selectionTool->AddItemToSel( newLine );
2250 newLine->SetFlags( STARTPOINT );
2251 }
2252 }
2253
2254 if( !lines.empty() )
2255 {
2257
2258 m_frame->OnModify();
2260
2261 m_toolMgr->RunAction( EE_ACTIONS::drag, false, true );
2262 }
2263
2264 return 0;
2265}
2266
2267
2269{
2271 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2272
2273 if( !sheet || !sheet->HasUndefinedPins() )
2274 return 0;
2275
2276 if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
2277 return 0;
2278
2280
2281 sheet->CleanupSheet();
2282
2283 updateItem( sheet, true );
2284 m_frame->OnModify();
2285
2286 if( selection.IsHover() )
2288
2289 return 0;
2290}
2291
2292
2294{
2296
2297 if( selection.GetSize() > 1 )
2298 return 0;
2299
2300 SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
2301
2303
2304 SCH_SCREEN* screen;
2305
2306 if( sheet )
2307 {
2308 // When changing the page number of a selected sheet, the current screen owns the sheet.
2309 screen = m_frame->GetScreen();
2310
2311 instance.push_back( sheet );
2312 }
2313 else
2314 {
2315 SCH_SHEET_PATH prevInstance = instance;
2316
2317 // When change the page number in the screen, the previous screen owns the sheet.
2318 if( prevInstance.size() )
2319 {
2320 prevInstance.pop_back();
2321 screen = prevInstance.LastScreen();
2322 }
2323 else
2324 {
2325 // The root sheet and root screen are effectively the same thing.
2326 screen = m_frame->GetScreen();
2327 }
2328
2329 sheet = m_frame->GetCurrentSheet().Last();
2330 }
2331
2332 wxString msg;
2333 wxString sheetPath = instance.PathHumanReadable( false );
2334 wxString pageNumber = instance.GetPageNumber();
2335
2336 msg.Printf( _( "Enter page number for sheet path%s" ),
2337 ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath );
2338
2339 wxTextEntryDialog dlg( m_frame, msg, _( "Edit Sheet Page Number" ), pageNumber );
2340
2341 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space.
2342
2343 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() )
2344 return 0;
2345
2346 m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false );
2347
2348 instance.SetPageNumber( dlg.GetValue() );
2349
2350 if( instance == m_frame->GetCurrentSheet() )
2351 {
2352 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
2354 }
2355
2356 m_frame->OnModify();
2357
2358 return 0;
2359}
2360
2361
2363{
2364 wxString aFileName = *aEvent.Parameter<wxString*>();
2365 return ( m_frame->AddSheetAndUpdateDisplay( aFileName ) ? 0 : 1 );
2366}
2367
2368
2370{
2376 Go( &SCH_EDIT_TOOL::Swap, EE_ACTIONS::swap.MakeEvent() );
2379
2398
2401
2405
2407}
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:145
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:139
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:141
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:181
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:143
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:149
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:130
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:120
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:136
KIFONT::FONT * GetFont() const
Definition: eda_text.h:188
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:248
wxString GetHyperlink() const
Definition: eda_text.h:334
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:149
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:133
void SetHyperlink(wxString aLink)
Definition: eda_text.h:335
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:152
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:112
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:331
VECTOR2I GetTextSize() const
Definition: eda_text.h:196
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:125
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
static TOOL_ACTION properties
Definition: ee_actions.h:128
static TOOL_ACTION move
Definition: ee_actions.h:120
static TOOL_ACTION clearHighlight
Definition: ee_actions.h:250
static TOOL_ACTION toGLabel
Definition: ee_actions.h:140
static TOOL_ACTION cleanupSheetPins
Definition: ee_actions.h:209
static TOOL_ACTION slice
Definition: ee_actions.h:144
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
static TOOL_ACTION drag
Definition: ee_actions.h:121
static TOOL_ACTION toText
Definition: ee_actions.h:141
static TOOL_ACTION placeClassLabel
Definition: ee_actions.h:88
static TOOL_ACTION showDeMorganAlternate
Definition: ee_actions.h:135
static TOOL_ACTION autoplaceFields
Definition: ee_actions.h:132
static TOOL_ACTION showDeMorganStandard
Definition: ee_actions.h:134
static TOOL_ACTION rotateCCW
Definition: ee_actions.h:124
static TOOL_ACTION editValue
Definition: ee_actions.h:130
static TOOL_ACTION toLabel
Definition: ee_actions.h:137
static TOOL_ACTION toTextBox
Definition: ee_actions.h:142
static TOOL_ACTION breakWire
Definition: ee_actions.h:143
static TOOL_ACTION mirrorH
Definition: ee_actions.h:126
static TOOL_ACTION rotateCW
Definition: ee_actions.h:123
static TOOL_ACTION editWithLibEdit
Definition: ee_actions.h:170
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:255
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:163
static TOOL_ACTION changeSymbol
Definition: ee_actions.h:158
static TOOL_ACTION editFootprint
Definition: ee_actions.h:131
static TOOL_ACTION enterSheet
Definition: ee_actions.h:198
static TOOL_ACTION editReference
Definition: ee_actions.h:129
static TOOL_ACTION updateSymbols
Definition: ee_actions.h:157
static TOOL_ACTION placeSchematicText
Definition: ee_actions.h:93
static TOOL_ACTION changeSymbols
Definition: ee_actions.h:156
static TOOL_ACTION toCLabel
Definition: ee_actions.h:138
static TOOL_ACTION placeLabel
Definition: ee_actions.h:87
static TOOL_ACTION repeatDrawItem
Definition: ee_actions.h:122
static TOOL_ACTION toHLabel
Definition: ee_actions.h:139
static TOOL_ACTION editTextAndGraphics
Definition: ee_actions.h:210
static TOOL_ACTION swap
Definition: ee_actions.h:127
static TOOL_ACTION toggleDeMorgan
Definition: ee_actions.h:133
static TOOL_ACTION updateSymbol
Definition: ee_actions.h:159
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
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: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:213
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:101
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:1591
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1384
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:584
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:203
SCH_SHEET & Root() const
Definition: schematic.h:91
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.
bool SchematicCleanUp(SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void ConvertPart(SCH_SYMBOL *aSymbol)
Definition: picksymbol.cpp:278
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
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void 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 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:527
void 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 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.
static const std::vector< KICAD_T > RotatableItems
Definition: sch_edit_tool.h:42
EDA_ITEM * m_pickerItem
Definition: sch_edit_tool.h:93
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:51
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:723
int GetId() const
Definition: sch_field.h:125
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:813
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:349
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:342
virtual void MirrorHorizontally(int aCenter)=0
Mirror item horizontally about aCenter.
void ClearFieldsAutoplaced()
Definition: sch_item.h:427
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:442
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:436
virtual bool HasLineStroke() const
Check if this schematic item has line stoke properties.
Definition: sch_item.h:455
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:364
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
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.)
int AddJunctionsIfNeeded(EE_SELECTION *aSelection)
Handle the addition of junctions to a selection of objects.
int TrimOverLappingWires(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:395
void RotateStart(const VECTOR2I &aCenter)
Definition: sch_line.cpp:389
VECTOR2I GetEndPoint() const
Definition: sch_line.h:143
VECTOR2I GetStartPoint() const
Definition: sch_line.h:138
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:656
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:468
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:376
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 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:825
VECTOR2I GetRotationCenter() const
Rotating around the boundingBox's center can cause walking when the sheetname or filename is longer t...
Definition: sch_sheet.cpp:694
void CleanupSheet()
Delete sheet label which do not have a corresponding hierarchical label.
Definition: sch_sheet.cpp:556
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:380
bool HasUndefinedPins() const
Check all sheet labels against schematic for undefined hierarchical labels.
Definition: sch_sheet.cpp:442
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:106
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
Definition: sch_sheet.cpp:662
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_sheet.cpp:683
Schematic symbol object.
Definition: sch_symbol.h:81
int GetUnit() const
Definition: sch_symbol.h:228
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:843
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 IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:236
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:175
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:192
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 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 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: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 Empty() const
Checks if there is anything selected.
Definition: selection.h:109
bool HasReferencePoint() const
Definition: selection.h:247
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:215
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
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:380
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:419
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:420
#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_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
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
@ SYM_MIRROR_Y
@ SYM_MIRROR_X
#define HITTEST_THRESHOLD_PIXELS
static std::vector< KICAD_T > deletableItems
const std::vector< KICAD_T > swappableItems
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
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: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:618