KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_design_block_utils.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <pgm_base.h>
21#include <kiway.h>
22#include <design_block.h>
25#include <sch_edit_frame.h>
26#include <sch_group.h>
27#include <wx/choicdlg.h>
28#include <wx/msgdlg.h>
29#include <wx/textdlg.h>
31#include <paths.h>
32#include <env_paths.h>
33#include <common.h>
34#include <kidialog.h>
35#include <confirm.h>
36#include <tool/actions.h>
37#include <tool/tool_manager.h>
38#include <sch_selection_tool.h>
40#include <json_common.h>
41
42bool checkOverwriteDb( wxWindow* aFrame, wxString& libname, wxString& newName )
43{
44 wxString msg = wxString::Format( _( "Design block '%s' already exists in library '%s'." ),
45 newName.GetData(),
46 libname.GetData() );
47
48 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing design block?" ), _( "Overwrite" ) )
49 != wxID_OK )
50 {
51 return false;
52 }
53
54 return true;
55}
56
57
58bool checkOverwriteDbSchematic( wxWindow* aFrame, const LIB_ID& aLibId )
59{
60 wxString msg = wxString::Format( _( "Design block '%s' already has a schematic." ),
61 aLibId.GetUniStringLibItemName() );
62
63 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing schematic?" ), _( "Overwrite" ) )
64 != wxID_OK )
65 {
66 return false;
67 }
68
69 return true;
70}
71
72
73bool SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, SCH_SHEET_PATH& aSheetPath )
74{
75 // Make sure the user has selected a library to save into
76 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
77 {
78 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
79 return false;
80 }
81
82 // Just block all attempts to create design blocks with nested sheets at this point
83 std::vector<SCH_ITEM*> sheets;
84 aSheetPath.LastScreen()->GetSheets( &sheets );
85
86 if( !sheets.empty() )
87 {
88 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
89 return false;
90 }
91
92 DESIGN_BLOCK blk;
93 wxFileName fn = wxFileNameFromPath( aSheetPath.Last()->GetName() );
94
95 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
96
97 // Copy all fields from the sheet to the design block
98 for( SCH_FIELD& field : aSheetPath.Last()->GetFields() )
99 {
100 if( field.GetId() == FIELD_T::SHEET_NAME || field.GetId() == FIELD_T::SHEET_FILENAME )
101 continue;
102
103 blk.GetFields()[field.GetUntranslatedName()] = field.GetText();
104 }
105
106 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
107
108 if( dlg.ShowModal() != wxID_OK )
109 return false;
110
111 wxString libName = blk.GetLibId().GetLibNickname();
112 wxString newName = blk.GetLibId().GetLibItemName();
113
114 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
115 return false;
116
117 // Save a temporary copy of the schematic file, as the plugin is just going to move it
118 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
119
120 if( !saveSchematicFile( aSheetPath.Last(), tempFile ) )
121 {
122 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
123 wxRemoveFile( tempFile );
124 return false;
125 }
126
127 blk.SetSchematicFile( tempFile );
128
129 bool success = false;
130
131 try
132 {
133 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
135 }
136 catch( const IO_ERROR& ioe )
137 {
138 DisplayError( this, ioe.What() );
139 }
140
141 // Clean up the temporary file
142 wxRemoveFile( tempFile );
143
144 m_designBlocksPane->RefreshLibs();
145 m_designBlocksPane->SelectLibId( blk.GetLibId() );
146
147 return success;
148}
149
150
152{
153 // Make sure the user has selected a library to save into
154 if( !Prj().DesignBlockLibs()->DesignBlockExists( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) )
155 {
156 DisplayErrorMessage( this, _( "Please select a design block to save the schematic to." ) );
157 return false;
158 }
159
160 // Just block all attempts to create design blocks with nested sheets at this point
161 std::vector<SCH_ITEM*> sheets;
162 aSheetPath.LastScreen()->GetSheets( &sheets );
163
164 if( !sheets.empty() )
165 {
166 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
167 return false;
168 }
169
170 wxString error;
171 std::unique_ptr<DESIGN_BLOCK> blk;
172
173 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
174 &error ) );
175
176 if( !blk )
177 {
178 DisplayErrorMessage( this, error );
179 return false;
180 }
181
182 if( !blk->GetSchematicFile().IsEmpty() && !checkOverwriteDbSchematic( this, aLibId ) )
183 return false;
184
185 // Copy all fields from the sheet to the design block.
186 // Note: this will overwrite any existing fields in the design block, but
187 // will leave extra fields not in this source sheet alone.
188 for( SCH_FIELD& field : aSheetPath.Last()->GetFields() )
189 {
190 if( field.GetId() == FIELD_T::SHEET_NAME || field.GetId() == FIELD_T::SHEET_FILENAME )
191 continue;
192
193 blk->GetFields()[field.GetUntranslatedName()] = field.GetText();
194 }
195
196 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, blk.get(), true );
197
198 if( dlg.ShowModal() != wxID_OK )
199 return false;
200
201 // Save a temporary copy of the schematic file, as the plugin is just going to move it
202 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
203 if( !saveSchematicFile( aSheetPath.Last(), tempFile ) )
204 {
205 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
206 wxRemoveFile( tempFile );
207 return false;
208 }
209
210 blk->SetSchematicFile( tempFile );
211
212 bool success = false;
213
214 try
215 {
216 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
218 }
219 catch( const IO_ERROR& ioe )
220 {
221 DisplayError( this, ioe.What() );
222 }
223
224 // Clean up the temporary file
225 wxRemoveFile( tempFile );
226
227 m_designBlocksPane->RefreshLibs();
228 m_designBlocksPane->SelectLibId( blk->GetLibId() );
229
230 return success;
231}
232
233
234bool SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
235{
236 // Get all selected items
237 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
238
239 if( selection.Empty() )
240 {
241 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
242 return false;
243 }
244
245 // Make sure the user has selected a library to save into
246 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
247 {
248 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
249 return false;
250 }
251
252 // Just block all attempts to create design blocks with nested sheets at this point
253 if( selection.HasType( SCH_SHEET_T ) )
254 {
255 if( selection.Size() == 1 )
256 {
257 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
259
260 curPath.push_back( sheet );
261 SaveSheetAsDesignBlock( aLibraryName, curPath );
262 }
263 else
264 {
265 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
266 }
267
268 return false;
269 }
270
271 DESIGN_BLOCK blk;
272 SCH_GROUP* group = nullptr;
273
274 if( selection.Size() == 1 && selection.HasType( SCH_GROUP_T ) )
275 group = static_cast<SCH_GROUP*>( selection.Front() );
276
277 if( group && !group->GetName().IsEmpty() )
278 // If the user has selected a single group, they probably want the design block named after the group
279 blk.SetLibId( LIB_ID( aLibraryName, group->GetName() ) );
280 else
281 {
282 // Otherwise, use the current screen name
283 wxFileName fn = wxFileNameFromPath( GetScreen()->GetFileName() );
284 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
285 }
286
287 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
288
289 if( dlg.ShowModal() != wxID_OK )
290 return false;
291
292 wxString libName = blk.GetLibId().GetLibNickname();
293 wxString newName = blk.GetLibId().GetLibItemName();
294
295 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
296 return false;
297
298 // Create a temporary screen
299 SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic );
300
301 // If we have a single group, we want to strip the group and select the children
302 if( group )
303 {
304 selection.Remove( group );
305
306 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
307 group->RunOnChildren(
308 [&]( EDA_ITEM* aItem )
309 {
310 selection.Add( aItem );
311 },
313 }
314
315 // Copy the selected items to the temporary screen
316 for( EDA_ITEM* item : selection )
317 {
318 // We need to deep copy since selections of groups will not have the children
319 if( item->Type() == SCH_GROUP_T )
320 {
321 SCH_GROUP* clonedGroup = static_cast<SCH_GROUP*>( item )->DeepClone();
322
323 tempScreen->Append( clonedGroup );
324
325 clonedGroup->RunOnChildren(
326 [&]( EDA_ITEM* aItem )
327 {
328 tempScreen->Append( static_cast<SCH_ITEM*>( aItem ) );
329 },
331 }
332 else if( item->Type() == SCH_SYMBOL_T )
333 {
334 SCH_SYMBOL* clonedSymbol = static_cast<SCH_SYMBOL*>( item->Clone() );
335 tempScreen->Append( clonedSymbol );
336 }
337 else if( item->Type() == SCH_PIN_T || item->Type() == SCH_FIELD_T )
338 {
339 // Handled as symbol children
340 continue;
341 }
342 else
343 {
344 EDA_ITEM* copy = item->Clone();
345 tempScreen->Append( static_cast<SCH_ITEM*>( copy ) );
346 }
347 }
348
349 // Create a sheet for the temporary screen
350 SCH_SHEET* tempSheet = new SCH_SHEET( m_schematic );
351 tempSheet->SetScreen( tempScreen );
352
353 // Save a temporary copy of the schematic file, as the plugin is just going to move it
354 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
355 if( !saveSchematicFile( tempSheet, tempFile ) )
356 {
357 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
358 wxRemoveFile( tempFile );
359 return false;
360 }
361
362 blk.SetSchematicFile( tempFile );
363
364 bool success = false;
365
366 try
367 {
368 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
370 }
371 catch( const IO_ERROR& ioe )
372 {
373 DisplayError( this, ioe.What() );
374 }
375
376 if( success && !group )
377 {
378 SCH_COMMIT commit( m_toolManager );
379 SCH_SCREEN* screen = GetScreen();
380
381 SCH_GROUP* newGroup = new SCH_GROUP;
382 newGroup->SetParent( screen );
383 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
384 newGroup->SetDesignBlockLibId( blk.GetLibId() );
385
386 int addedCount = 0;
387
388 for( EDA_ITEM* edaItem : selection )
389 {
390 if( !edaItem->IsSCH_ITEM() )
391 continue;
392
393 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
394
395 if( item->GetParentSymbol() )
396 continue;
397
398 if( !item->IsGroupableType() )
399 continue;
400
401 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
402 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
403
404 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
405 newGroup->AddItem( item );
406 addedCount++;
407 }
408
409 if( addedCount > 0 )
410 {
411 commit.Add( newGroup, screen );
412 commit.Push( _( "Group Items" ) );
413
415 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
416 }
417 else
418 {
419 newGroup->RemoveAll();
420 delete newGroup;
421 }
422 }
423 else if( success && group && !group->HasDesignBlockLink() )
424 {
425 SCH_COMMIT commit( m_toolManager );
426
427 commit.Modify( group, GetScreen() );
428 group->SetDesignBlockLibId( blk.GetLibId() );
429
430 commit.Push( _( "Set Group Design Block Link" ) );
431 }
432
433 // Clean up the temporaries
434 wxRemoveFile( tempFile );
435 // This will also delete the screen
436 delete tempSheet;
437
438 m_designBlocksPane->RefreshLibs();
439 m_designBlocksPane->SelectLibId( blk.GetLibId() );
440
441 return success;
442}
443
444
446{
447 // Get all selected items
448 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
449
450 if( selection.Empty() )
451 {
452 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
453 return false;
454 }
455
456 // Make sure the user has selected a library to save into
457 if( !Prj().DesignBlockLibs()->DesignBlockExists( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) )
458 {
459 DisplayErrorMessage( this, _( "Please select a design block to save the schematic to." ) );
460 return false;
461 }
462
463 // Just block all attempts to create design blocks with nested sheets at this point
464 if( selection.HasType( SCH_SHEET_T ) )
465 {
466 if( selection.Size() == 1 )
467 {
468 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
470
471 curPath.push_back( sheet );
472 UpdateDesignBlockFromSheet( aLibId, curPath );
473 }
474 else
475 {
476 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
477 }
478
479 return false;
480 }
481
482 // If the selection is a single group, or contains this block's linked group plus extra items,
483 // we want to strip the group and select the children
484 SCH_GROUP* group = nullptr;
485 std::vector<SCH_ITEM*> extraItems;
486
487 if( selection.Size() == 1 )
488 {
489 EDA_ITEM* item = selection.Front();
490
491 if( item->Type() == SCH_GROUP_T )
492 group = static_cast<SCH_GROUP*>( item );
493 }
494 else
495 {
496 for( EDA_ITEM* item : selection )
497 {
498 if( item->Type() != SCH_GROUP_T )
499 continue;
500
501 if( static_cast<SCH_GROUP*>( item )->GetDesignBlockLibId() != aLibId )
502 continue;
503
504 if( group )
505 {
506 DisplayErrorMessage( this, _( "The selection contains more than one group linked to "
507 "this design block." ) );
508 return false;
509 }
510
511 group = static_cast<SCH_GROUP*>( item );
512 }
513 }
514
515 if( group )
516 {
517 for( EDA_ITEM* item : selection )
518 {
519 if( item != group && item->IsSCH_ITEM() )
520 extraItems.push_back( static_cast<SCH_ITEM*>( item ) );
521 }
522
523 selection.Remove( group );
524
525 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
526 group->RunOnChildren(
527 [&]( EDA_ITEM* aItem )
528 {
529 selection.Add( aItem );
530 },
532 }
533
534 wxString error;
535 std::unique_ptr<DESIGN_BLOCK> blk;
536
537 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
538 &error ) );
539
540 if( !blk )
541 {
542 DisplayErrorMessage( this, error );
543 return false;
544 }
545
546 if( !blk->GetSchematicFile().IsEmpty() && !checkOverwriteDbSchematic( this, aLibId ) )
547 return false;
548
549 // Create a temporary screen
550 SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic );
551
552 auto cloneAndAdd =
553 [&] ( EDA_ITEM* aItem ) -> SCH_ITEM*
554 {
555 if( !aItem->IsSCH_ITEM() )
556 return nullptr;
557
558 SCH_ITEM* copy = static_cast<SCH_ITEM*>( aItem->Clone() );
559 tempScreen->Append( static_cast<SCH_ITEM*>( copy ) );
560 return copy;
561 };
562
563 // Copy the selected items to the temporary board
564 for( EDA_ITEM* item : selection )
565 {
566 // Remove parent group membership since we strip the first group layer
567 if( SCH_ITEM* copy = cloneAndAdd( item ) )
568 copy->SetParentGroup( nullptr );
569
570 if( item->Type() == SCH_GROUP_T )
571 {
572 SCH_GROUP* innerGroup = static_cast<SCH_GROUP*>( item );
573
574 // Groups also need their children copied
575 innerGroup->RunOnChildren( cloneAndAdd, RECURSE_MODE::RECURSE );
576 }
577 }
578
579 // Create a sheet for the temporary screen
580 SCH_SHEET* tempSheet = new SCH_SHEET( m_schematic );
581 tempSheet->SetScreen( tempScreen );
582
583 // Save a temporary copy of the schematic file, as the plugin is just going to move it
584 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
585
586 if( !saveSchematicFile( tempSheet, tempFile ) )
587 {
588 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
589 wxRemoveFile( tempFile );
590 return false;
591 }
592
593 blk->SetSchematicFile( tempFile );
594
595 bool success = false;
596
597 try
598 {
599 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
601
602 // If we had a group, extend it with the extra items and reselect it
603 if( group )
604 {
605 selection.Clear();
606 selection.Add( group );
607
608 SCH_COMMIT commit( m_toolManager );
609 SCH_SCREEN* screen = GetScreen();
610 bool changed = false;
611
612 for( SCH_ITEM* item : extraItems )
613 {
614 if( item->GetParentSymbol() || !item->IsGroupableType() )
615 continue;
616
617 if( item->GetParentGroup() == group )
618 continue;
619
620 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
621 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
622
623 if( !changed )
624 commit.Modify( group, screen, RECURSE_MODE::NO_RECURSE );
625
626 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
627 group->AddItem( item );
628 changed = true;
629 }
630
631 // If we didn't have a design block link before, add one for convenience
632 if( !group->HasDesignBlockLink() )
633 {
634 commit.Modify( group, screen, RECURSE_MODE::NO_RECURSE );
635 group->SetDesignBlockLibId( aLibId );
636 changed = true;
637 }
638
639 if( changed )
640 commit.Push( _( "Update Design Block Group" ) );
641 }
642 }
643 catch( const IO_ERROR& ioe )
644 {
645 DisplayError( this, ioe.What() );
646 }
647
648 if( success && !group )
649 {
650 SCH_COMMIT commit( m_toolManager );
651 SCH_SCREEN* screen = GetScreen();
652
653 SCH_GROUP* newGroup = new SCH_GROUP;
654 newGroup->SetParent( screen );
655 newGroup->SetName( aLibId.GetUniStringLibItemName() );
656 newGroup->SetDesignBlockLibId( aLibId );
657
658 int addedCount = 0;
659
660 for( EDA_ITEM* edaItem : selection )
661 {
662 if( !edaItem->IsSCH_ITEM() )
663 continue;
664
665 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
666
667 if( item->GetParentSymbol() )
668 continue;
669
670 if( !item->IsGroupableType() )
671 continue;
672
673 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
674 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
675
676 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
677 newGroup->AddItem( item );
678 addedCount++;
679 }
680
681 if( addedCount > 0 )
682 {
683 commit.Add( newGroup, screen );
684 commit.Push( _( "Group Items" ) );
685
687 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
688 }
689 else
690 {
691 newGroup->RemoveAll();
692 delete newGroup;
693 }
694 }
695
696 // Clean up the temporaries
697 wxRemoveFile( tempFile );
698 // This will also delete the screen
699 delete tempSheet;
700
701 m_designBlocksPane->RefreshLibs();
702 m_designBlocksPane->SelectLibId( blk->GetLibId() );
703
704 return success;
705}
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:223
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:74
SAVE_T SaveDesignBlock(const wxString &aNickname, const DESIGN_BLOCK *aDesignBlock, bool aOverwrite=true)
Write aDesignBlock to an existing library given by aNickname.
void SetSchematicFile(const wxString &aFile)
void SetLibId(const LIB_ID &aName)
const LIB_ID & GetLibId() const
const nlohmann::ordered_map< wxString, wxString > & GetFields() const
int ShowModal() override
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:43
void RemoveAll()
Definition eda_group.cpp:86
void SetDesignBlockLibId(const LIB_ID &aLibId)
Definition eda_group.h:87
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:58
void SetName(const wxString &aName)
Definition eda_group.h:62
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition lib_id.h:108
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
virtual DESIGN_BLOCK_LIBRARY_ADAPTER * DesignBlockLibs()
Return the table of design block libraries.
Definition project.cpp:433
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool UpdateDesignBlockFromSelection(const LIB_ID &aLibId)
SCHEMATIC * m_schematic
The currently loaded schematic.
SCH_SHEET_PATH & GetCurrentSheet() const
bool saveSchematicFile(SCH_SHEET *aSheet, const wxString &aSavePath)
Save aSheet to a schematic file.
SCH_DESIGN_BLOCK_PANE * m_designBlocksPane
bool SaveSheetAsDesignBlock(const wxString &aLibraryName, SCH_SHEET_PATH &aSheetPath)
bool UpdateDesignBlockFromSheet(const LIB_ID &aLibId, SCH_SHEET_PATH &aSheetPath)
bool SaveSelectionAsDesignBlock(const wxString &aLibraryName)
A set of SCH_ITEMs (i.e., without duplicates).
Definition sch_group.h:48
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
EDA_ITEM * AsEdaItem() override
Definition sch_group.h:60
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:165
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:287
bool IsGroupableType() const
Definition sch_item.cpp:123
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
Definition sch_sheet.h:91
wxString GetName() const
Definition sch_sheet.h:142
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Schematic symbol object.
Definition sch_symbol.h:75
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
Definition selection.cpp:38
virtual void Remove(EDA_ITEM *aItem)
Definition selection.cpp:60
EDA_ITEM * Front() const
Definition selection.h:176
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:97
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
int Size() const
Returns the number of selected parts.
Definition selection.h:120
bool Empty() const
Checks if there is anything selected.
Definition selection.h:114
TOOL_MANAGER * m_toolManager
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition confirm.cpp:165
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
This file is part of the common library.
#define _(s)
@ RECURSE
Definition eda_item.h:51
@ NO_RECURSE
Definition eda_item.h:52
Helper functions to substitute paths with environmental variables.
PROJECT & Prj()
Definition kicad.cpp:727
see class PGM_BASE
bool checkOverwriteDb(wxWindow *aFrame, wxString &libname, wxString &newName)
bool checkOverwriteDbSchematic(wxWindow *aFrame, const LIB_ID &aLibId)
Class to handle a set of SCH_ITEMs.
@ SCH_GROUP_T
Definition typeinfo.h:169
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_FIELD_T
Definition typeinfo.h:146
@ SCH_SHEET_T
Definition typeinfo.h:171
@ SCH_PIN_T
Definition typeinfo.h:149
Definition of file extensions used in Kicad.