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, true ) )
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
204 if( !saveSchematicFile( aSheetPath.Last(), tempFile, true ) )
205 {
206 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
207 wxRemoveFile( tempFile );
208 return false;
209 }
210
211 blk->SetSchematicFile( tempFile );
212
213 bool success = false;
214
215 try
216 {
217 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
219 }
220 catch( const IO_ERROR& ioe )
221 {
222 DisplayError( this, ioe.What() );
223 }
224
225 // Clean up the temporary file
226 wxRemoveFile( tempFile );
227
228 m_designBlocksPane->RefreshLibs();
229 m_designBlocksPane->SelectLibId( blk->GetLibId() );
230
231 return success;
232}
233
234
235bool SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
236{
237 // Get all selected items
238 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
239
240 if( selection.Empty() )
241 {
242 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
243 return false;
244 }
245
246 // Make sure the user has selected a library to save into
247 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
248 {
249 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
250 return false;
251 }
252
253 // Just block all attempts to create design blocks with nested sheets at this point
254 if( selection.HasType( SCH_SHEET_T ) )
255 {
256 if( selection.Size() == 1 )
257 {
258 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
260
261 curPath.push_back( sheet );
262 return SaveSheetAsDesignBlock( aLibraryName, curPath );
263 }
264 else
265 {
266 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
267 return false;
268 }
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 std::unique_ptr<SCH_SHEET> tempSheet = std::make_unique<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
356 if( !saveSchematicFile( tempSheet.get(), tempFile, true ) )
357 {
358 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
359 wxRemoveFile( tempFile );
360 return false;
361 }
362
363 blk.SetSchematicFile( tempFile );
364
365 bool success = false;
366
367 try
368 {
369 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
371 }
372 catch( const IO_ERROR& ioe )
373 {
374 DisplayError( this, ioe.What() );
375 }
376
377 if( success && !group )
378 {
379 SCH_COMMIT commit( m_toolManager );
380 SCH_SCREEN* screen = GetScreen();
381
382 SCH_GROUP* newGroup = new SCH_GROUP;
383 newGroup->SetParent( screen );
384 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
385 newGroup->SetDesignBlockLibId( blk.GetLibId() );
386
387 int addedCount = 0;
388
389 for( EDA_ITEM* edaItem : selection )
390 {
391 if( !edaItem->IsSCH_ITEM() )
392 continue;
393
394 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
395
396 if( item->GetParentSymbol() )
397 continue;
398
399 if( !item->IsGroupableType() )
400 continue;
401
402 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
403 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
404
405 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
406 newGroup->AddItem( item );
407 addedCount++;
408 }
409
410 if( addedCount > 0 )
411 {
412 commit.Add( newGroup, screen );
413 commit.Push( _( "Group Items" ) );
414
416 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
417 }
418 else
419 {
420 newGroup->RemoveAll();
421 delete newGroup;
422 }
423 }
424 else if( success && group && !group->HasDesignBlockLink() )
425 {
426 SCH_COMMIT commit( m_toolManager );
427
428 commit.Modify( group, GetScreen() );
429 group->SetDesignBlockLibId( blk.GetLibId() );
430
431 commit.Push( _( "Set Group Design Block Link" ) );
432 }
433
434 // Clean up the temporaries
435 wxRemoveFile( tempFile );
436
437 m_designBlocksPane->RefreshLibs();
438 m_designBlocksPane->SelectLibId( blk.GetLibId() );
439
440 return success;
441}
442
443
445{
446 // Get all selected items
447 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
448
449 if( selection.Empty() )
450 {
451 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
452 return false;
453 }
454
455 // Make sure the user has selected a library to save into
456 if( !Prj().DesignBlockLibs()->DesignBlockExists( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) )
457 {
458 DisplayErrorMessage( this, _( "Please select a design block to save the schematic to." ) );
459 return false;
460 }
461
462 // Just block all attempts to create design blocks with nested sheets at this point
463 if( selection.HasType( SCH_SHEET_T ) )
464 {
465 if( selection.Size() == 1 )
466 {
467 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
469
470 curPath.push_back( sheet );
471 return UpdateDesignBlockFromSheet( aLibId, curPath );
472 }
473 else
474 {
475 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
476 return false;
477 }
478 }
479
480 // If the selection is a single group, or contains this block's linked group plus extra items,
481 // we want to strip the group and select the children
482 SCH_GROUP* group = nullptr;
483 std::vector<SCH_ITEM*> extraItems;
484
485 if( selection.Size() == 1 )
486 {
487 EDA_ITEM* item = selection.Front();
488
489 if( item->Type() == SCH_GROUP_T )
490 group = static_cast<SCH_GROUP*>( item );
491 }
492 else
493 {
494 for( EDA_ITEM* item : selection )
495 {
496 if( item->Type() != SCH_GROUP_T )
497 continue;
498
499 if( static_cast<SCH_GROUP*>( item )->GetDesignBlockLibId() != aLibId )
500 continue;
501
502 if( group )
503 {
504 DisplayErrorMessage( this, _( "The selection contains more than one group linked to "
505 "this design block." ) );
506 return false;
507 }
508
509 group = static_cast<SCH_GROUP*>( item );
510 }
511 }
512
513 if( group )
514 {
515 for( EDA_ITEM* item : selection )
516 {
517 if( item != group && item->IsSCH_ITEM() )
518 extraItems.push_back( static_cast<SCH_ITEM*>( item ) );
519 }
520
521 selection.Remove( group );
522
523 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
524 group->RunOnChildren(
525 [&]( EDA_ITEM* aItem )
526 {
527 selection.Add( aItem );
528 },
530 }
531
532 wxString error;
533 std::unique_ptr<DESIGN_BLOCK> blk;
534
535 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
536 &error ) );
537
538 if( !blk )
539 {
540 DisplayErrorMessage( this, error );
541 return false;
542 }
543
544 if( !blk->GetSchematicFile().IsEmpty() && !checkOverwriteDbSchematic( this, aLibId ) )
545 return false;
546
547 // Create a temporary screen
548 SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic );
549
550 auto cloneAndAdd =
551 [&] ( EDA_ITEM* aItem ) -> SCH_ITEM*
552 {
553 if( !aItem->IsSCH_ITEM() )
554 return nullptr;
555
556 SCH_ITEM* copy = static_cast<SCH_ITEM*>( aItem->Clone() );
557 tempScreen->Append( static_cast<SCH_ITEM*>( copy ) );
558 return copy;
559 };
560
561 // Copy the selected items to the temporary board
562 for( EDA_ITEM* item : selection )
563 {
564 // Remove parent group membership since we strip the first group layer
565 if( SCH_ITEM* copy = cloneAndAdd( item ) )
566 copy->SetParentGroup( nullptr );
567
568 if( item->Type() == SCH_GROUP_T )
569 {
570 SCH_GROUP* innerGroup = static_cast<SCH_GROUP*>( item );
571
572 // Groups also need their children copied
573 innerGroup->RunOnChildren( cloneAndAdd, RECURSE_MODE::RECURSE );
574 }
575 }
576
577 // Create a sheet for the temporary screen
578 std::unique_ptr<SCH_SHEET> tempSheet = std::make_unique<SCH_SHEET>( m_schematic );
579 tempSheet->SetScreen( tempScreen );
580
581 // Save a temporary copy of the schematic file, as the plugin is just going to move it
582 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
583
584 if( !saveSchematicFile( tempSheet.get(), tempFile, true ) )
585 {
586 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
587 wxRemoveFile( tempFile );
588 return false;
589 }
590
591 blk->SetSchematicFile( tempFile );
592
593 bool success = false;
594
595 try
596 {
597 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
599
600 // If we had a group, extend it with the extra items and reselect it
601 if( group )
602 {
603 selection.Clear();
604 selection.Add( group );
605
606 SCH_COMMIT commit( m_toolManager );
607 SCH_SCREEN* screen = GetScreen();
608 bool changed = false;
609
610 for( SCH_ITEM* item : extraItems )
611 {
612 if( item->GetParentSymbol() || !item->IsGroupableType() )
613 continue;
614
615 if( item->GetParentGroup() == group )
616 continue;
617
618 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
619 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
620
621 if( !changed )
622 commit.Modify( group, screen, RECURSE_MODE::NO_RECURSE );
623
624 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
625 group->AddItem( item );
626 changed = true;
627 }
628
629 // If we didn't have a design block link before, add one for convenience
630 if( !group->HasDesignBlockLink() )
631 {
632 commit.Modify( group, screen, RECURSE_MODE::NO_RECURSE );
633 group->SetDesignBlockLibId( aLibId );
634 changed = true;
635 }
636
637 if( changed )
638 commit.Push( _( "Update Design Block Group" ) );
639 }
640 }
641 catch( const IO_ERROR& ioe )
642 {
643 DisplayError( this, ioe.What() );
644 }
645
646 if( success && !group )
647 {
648 SCH_COMMIT commit( m_toolManager );
649 SCH_SCREEN* screen = GetScreen();
650
651 SCH_GROUP* newGroup = new SCH_GROUP;
652 newGroup->SetParent( screen );
653 newGroup->SetName( aLibId.GetUniStringLibItemName() );
654 newGroup->SetDesignBlockLibId( aLibId );
655
656 int addedCount = 0;
657
658 for( EDA_ITEM* edaItem : selection )
659 {
660 if( !edaItem->IsSCH_ITEM() )
661 continue;
662
663 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
664
665 if( item->GetParentSymbol() )
666 continue;
667
668 if( !item->IsGroupableType() )
669 continue;
670
671 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
672 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
673
674 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
675 newGroup->AddItem( item );
676 addedCount++;
677 }
678
679 if( addedCount > 0 )
680 {
681 commit.Add( newGroup, screen );
682 commit.Push( _( "Group Items" ) );
683
685 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
686 }
687 else
688 {
689 newGroup->RemoveAll();
690 delete newGroup;
691 }
692 }
693
694 // Clean up the temporaries
695 wxRemoveFile( tempFile );
696
697 m_designBlocksPane->RefreshLibs();
698 m_designBlocksPane->SelectLibId( blk->GetLibId() );
699
700 return success;
701}
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:101
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:58
void SetName(const wxString &aName)
Definition eda_group.h:76
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
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
void Push(const wxString &aMessage=wxEmptyString, 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)
bool saveSchematicFile(SCH_SHEET *aSheet, const wxString &aSavePath, bool isSaveAs)
Save aSheet to a schematic file.
SCHEMATIC * m_schematic
The currently loaded schematic.
SCH_SHEET_PATH & GetCurrentSheet() const
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:170
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:350
bool IsGroupableType() const
Definition sch_item.cpp:144
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
Schematic symbol object.
Definition sch_symbol.h:73
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:733
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.