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.GetCanonicalName()] = 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 std::unique_ptr<DESIGN_BLOCK> blk;
171
172 try
173 {
174 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) );
175 }
176 catch( const IO_ERROR& ioe )
177 {
178 DisplayError( this, ioe.What() );
179 return false;
180 }
181
182 if( !blk )
183 {
185 this, wxString::Format( _( "Design block '%s' does not exist." ), aLibId.GetUniStringLibItemName() ) );
186 return false;
187 }
188
189 if( !blk->GetSchematicFile().IsEmpty() && !checkOverwriteDbSchematic( this, aLibId ) )
190 return false;
191
192 // Copy all fields from the sheet to the design block.
193 // Note: this will overwrite any existing fields in the design block, but
194 // will leave extra fields not in this source sheet alone.
195 for( SCH_FIELD& field : aSheetPath.Last()->GetFields() )
196 {
197 if( field.GetId() == FIELD_T::SHEET_NAME || field.GetId() == FIELD_T::SHEET_FILENAME )
198 continue;
199
200 blk->GetFields()[field.GetCanonicalName()] = field.GetText();
201 }
202
203 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, blk.get(), true );
204
205 if( dlg.ShowModal() != wxID_OK )
206 return false;
207
208 // Save a temporary copy of the schematic file, as the plugin is just going to move it
209 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
210 if( !saveSchematicFile( aSheetPath.Last(), tempFile ) )
211 {
212 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
213 wxRemoveFile( tempFile );
214 return false;
215 }
216
217 blk->SetSchematicFile( tempFile );
218
219 bool success = false;
220
221 try
222 {
223 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
225 }
226 catch( const IO_ERROR& ioe )
227 {
228 DisplayError( this, ioe.What() );
229 }
230
231 // Clean up the temporary file
232 wxRemoveFile( tempFile );
233
234 m_designBlocksPane->RefreshLibs();
235 m_designBlocksPane->SelectLibId( blk->GetLibId() );
236
237 return success;
238}
239
240
241bool SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
242{
243 // Get all selected items
244 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
245
246 if( selection.Empty() )
247 {
248 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
249 return false;
250 }
251
252 // Make sure the user has selected a library to save into
253 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
254 {
255 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
256 return false;
257 }
258
259 // Just block all attempts to create design blocks with nested sheets at this point
260 if( selection.HasType( SCH_SHEET_T ) )
261 {
262 if( selection.Size() == 1 )
263 {
264 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
266
267 curPath.push_back( sheet );
268 SaveSheetAsDesignBlock( aLibraryName, curPath );
269 }
270 else
271 {
272 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
273 }
274
275 return false;
276 }
277
278 DESIGN_BLOCK blk;
279 SCH_GROUP* group = nullptr;
280
281 if( selection.Size() == 1 && selection.HasType( SCH_GROUP_T ) )
282 group = static_cast<SCH_GROUP*>( selection.Front() );
283
284 if( group && !group->GetName().IsEmpty() )
285 // If the user has selected a single group, they probably want the design block named after the group
286 blk.SetLibId( LIB_ID( aLibraryName, group->GetName() ) );
287 else
288 {
289 // Otherwise, use the current screen name
290 wxFileName fn = wxFileNameFromPath( GetScreen()->GetFileName() );
291 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
292 }
293
294 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
295
296 if( dlg.ShowModal() != wxID_OK )
297 return false;
298
299 wxString libName = blk.GetLibId().GetLibNickname();
300 wxString newName = blk.GetLibId().GetLibItemName();
301
302 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
303 return false;
304
305 // Create a temporary screen
306 SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic );
307
308 // If we have a single group, we want to strip the group and select the children
309 if( group )
310 {
311 selection.Remove( group );
312
313 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
314 group->RunOnChildren(
315 [&]( EDA_ITEM* aItem )
316 {
317 selection.Add( aItem );
318 },
320 }
321
322 // Copy the selected items to the temporary screen
323 for( EDA_ITEM* item : selection )
324 {
325 // We need to deep copy since selections of groups will not have the children
326 if( item->Type() == SCH_GROUP_T )
327 {
328 SCH_GROUP* clonedGroup = static_cast<SCH_GROUP*>( item )->DeepClone();
329
330 tempScreen->Append( clonedGroup );
331
332 clonedGroup->RunOnChildren(
333 [&]( EDA_ITEM* aItem )
334 {
335 tempScreen->Append( static_cast<SCH_ITEM*>( aItem ) );
336 },
338 }
339 else if( item->Type() == SCH_SYMBOL_T )
340 {
341 SCH_SYMBOL* clonedSymbol = static_cast<SCH_SYMBOL*>( item->Clone() );
342 tempScreen->Append( clonedSymbol );
343 }
344 else if( item->Type() == SCH_PIN_T || item->Type() == SCH_FIELD_T )
345 {
346 // Handled as symbol children
347 continue;
348 }
349 else
350 {
351 EDA_ITEM* copy = item->Clone();
352 tempScreen->Append( static_cast<SCH_ITEM*>( copy ) );
353 }
354 }
355
356 // Create a sheet for the temporary screen
357 SCH_SHEET* tempSheet = new SCH_SHEET( m_schematic );
358 tempSheet->SetScreen( tempScreen );
359
360 // Save a temporary copy of the schematic file, as the plugin is just going to move it
361 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
362 if( !saveSchematicFile( tempSheet, tempFile ) )
363 {
364 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
365 wxRemoveFile( tempFile );
366 return false;
367 }
368
369 blk.SetSchematicFile( tempFile );
370
371 bool success = false;
372
373 try
374 {
375 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
377 }
378 catch( const IO_ERROR& ioe )
379 {
380 DisplayError( this, ioe.What() );
381 }
382
383 if( success && !group )
384 {
385 SCH_COMMIT commit( m_toolManager );
386 SCH_SCREEN* screen = GetScreen();
387
388 SCH_GROUP* newGroup = new SCH_GROUP;
389 newGroup->SetParent( screen );
390 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
391 newGroup->SetDesignBlockLibId( blk.GetLibId() );
392
393 int addedCount = 0;
394
395 for( EDA_ITEM* edaItem : selection )
396 {
397 if( !edaItem->IsSCH_ITEM() )
398 continue;
399
400 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
401
402 if( item->GetParentSymbol() )
403 continue;
404
405 if( !item->IsGroupableType() )
406 continue;
407
408 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
409 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
410
411 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
412 newGroup->AddItem( item );
413 addedCount++;
414 }
415
416 if( addedCount > 0 )
417 {
418 commit.Add( newGroup, screen );
419 commit.Push( _( "Group Items" ) );
420
422 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
423 }
424 else
425 {
426 newGroup->RemoveAll();
427 delete newGroup;
428 }
429 }
430 else if( success && group && !group->HasDesignBlockLink() )
431 {
432 SCH_COMMIT commit( m_toolManager );
433
434 commit.Modify( group, GetScreen() );
435 group->SetDesignBlockLibId( blk.GetLibId() );
436
437 commit.Push( _( "Set Group Design Block Link" ) );
438 }
439
440 // Clean up the temporaries
441 wxRemoveFile( tempFile );
442 // This will also delete the screen
443 delete tempSheet;
444
445 m_designBlocksPane->RefreshLibs();
446 m_designBlocksPane->SelectLibId( blk.GetLibId() );
447
448 return success;
449}
450
451
453{
454 // Get all selected items
455 SCH_SELECTION selection = m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
456
457 if( selection.Empty() )
458 {
459 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
460 return false;
461 }
462
463 // Make sure the user has selected a library to save into
464 if( !Prj().DesignBlockLibs()->DesignBlockExists( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) )
465 {
466 DisplayErrorMessage( this, _( "Please select a design block to save the schematic to." ) );
467 return false;
468 }
469
470 // Just block all attempts to create design blocks with nested sheets at this point
471 if( selection.HasType( SCH_SHEET_T ) )
472 {
473 if( selection.Size() == 1 )
474 {
475 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( selection.Front() );
477
478 curPath.push_back( sheet );
479 UpdateDesignBlockFromSheet( aLibId, curPath );
480 }
481 else
482 {
483 DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) );
484 }
485
486 return false;
487 }
488
489 // If we have a single group, we want to strip the group and select the children
490 SCH_GROUP* group = nullptr;
491
492 if( selection.Size() == 1 )
493 {
494 EDA_ITEM* item = selection.Front();
495
496 if( item->Type() == SCH_GROUP_T )
497 {
498 group = static_cast<SCH_GROUP*>( item );
499
500 selection.Remove( group );
501
502 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
503 group->RunOnChildren( [&]( EDA_ITEM* aItem )
504 {
505 selection.Add( aItem );
506 },
508 }
509 }
510
511 std::unique_ptr<DESIGN_BLOCK> blk;
512
513 try
514 {
515 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) );
516 }
517 catch( const IO_ERROR& ioe )
518 {
519 DisplayError( this, ioe.What() );
520 return false;
521 }
522
523 if( !blk )
524 {
526 this, wxString::Format( _( "Design block '%s' does not exist." ), aLibId.GetUniStringLibItemName() ) );
527 return false;
528 }
529
530 if( !blk->GetSchematicFile().IsEmpty() && !checkOverwriteDbSchematic( this, aLibId ) )
531 return false;
532
533 // Create a temporary screen
534 SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic );
535
536 auto cloneAndAdd =
537 [&] ( EDA_ITEM* aItem ) -> SCH_ITEM*
538 {
539 if( !aItem->IsSCH_ITEM() )
540 return nullptr;
541
542 SCH_ITEM* copy = static_cast<SCH_ITEM*>( aItem->Clone() );
543 tempScreen->Append( static_cast<SCH_ITEM*>( copy ) );
544 return copy;
545 };
546
547 // Copy the selected items to the temporary board
548 for( EDA_ITEM* item : selection )
549 {
550 // Remove parent group membership since we strip the first group layer
551 if( SCH_ITEM* copy = cloneAndAdd( item ) )
552 copy->SetParentGroup( nullptr );
553
554 if( item->Type() == SCH_GROUP_T )
555 {
556 SCH_GROUP* innerGroup = static_cast<SCH_GROUP*>( item );
557
558 // Groups also need their children copied
559 innerGroup->RunOnChildren( cloneAndAdd, RECURSE_MODE::RECURSE );
560 }
561 }
562
563 // Create a sheet for the temporary screen
564 SCH_SHEET* tempSheet = new SCH_SHEET( m_schematic );
565 tempSheet->SetScreen( tempScreen );
566
567 // Save a temporary copy of the schematic file, as the plugin is just going to move it
568 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
569
570 if( !saveSchematicFile( tempSheet, tempFile ) )
571 {
572 DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) );
573 wxRemoveFile( tempFile );
574 return false;
575 }
576
577 blk->SetSchematicFile( tempFile );
578
579 bool success = false;
580
581 try
582 {
583 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
585
586 // If we had a group, we need to reselect it
587 if( group )
588 {
589 selection.Clear();
590 selection.Add( group );
591
592 // If we didn't have a design block link before, add one for convenience
593 if( !group->HasDesignBlockLink() )
594 {
595 SCH_COMMIT commit( m_toolManager );
596
597 commit.Modify( group, GetScreen() );
598 group->SetDesignBlockLibId( aLibId );
599
600 commit.Push( _( "Set Group Design Block Link" ) );
601 }
602 }
603 }
604 catch( const IO_ERROR& ioe )
605 {
606 DisplayError( this, ioe.What() );
607 }
608
609 if( success && !group )
610 {
611 SCH_COMMIT commit( m_toolManager );
612 SCH_SCREEN* screen = GetScreen();
613
614 SCH_GROUP* newGroup = new SCH_GROUP;
615 newGroup->SetParent( screen );
616 newGroup->SetName( aLibId.GetUniStringLibItemName() );
617 newGroup->SetDesignBlockLibId( aLibId );
618
619 int addedCount = 0;
620
621 for( EDA_ITEM* edaItem : selection )
622 {
623 if( !edaItem->IsSCH_ITEM() )
624 continue;
625
626 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
627
628 if( item->GetParentSymbol() )
629 continue;
630
631 if( !item->IsGroupableType() )
632 continue;
633
634 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
635 commit.Modify( existingGroup->AsEdaItem(), screen, RECURSE_MODE::NO_RECURSE );
636
637 commit.Modify( item, screen, RECURSE_MODE::NO_RECURSE );
638 newGroup->AddItem( item );
639 addedCount++;
640 }
641
642 if( addedCount > 0 )
643 {
644 commit.Add( newGroup, screen );
645 commit.Push( _( "Group Items" ) );
646
648 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
649 }
650 else
651 {
652 newGroup->RemoveAll();
653 delete newGroup;
654 }
655 }
656
657 // Clean up the temporaries
658 wxRemoveFile( tempFile );
659 // This will also delete the screen
660 delete tempSheet;
661
662 m_designBlocksPane->RefreshLibs();
663 m_designBlocksPane->SelectLibId( blk->GetLibId() );
664
665 return success;
666}
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:42
void RemoveAll()
Definition eda_group.cpp:86
void SetDesignBlockLibId(const LIB_ID &aLibId)
Definition eda_group.h:73
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:58
void SetName(const wxString &aName)
Definition eda_group.h:48
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:114
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
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:59
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:274
bool IsGroupableType() const
Definition sch_item.cpp:113
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:44
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
Definition sch_sheet.h:87
wxString GetName() const
Definition sch_sheet.h:136
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Schematic symbol object.
Definition sch_symbol.h:69
virtual void Add(EDA_ITEM *aItem)
Definition selection.cpp:38
virtual void Remove(EDA_ITEM *aItem)
Definition selection.cpp:56
EDA_ITEM * Front() const
Definition selection.h:173
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:94
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:117
bool Empty() const
Checks if there is anything selected.
Definition selection.h:111
TOOL_MANAGER * m_toolManager
The common library.
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:49
@ NO_RECURSE
Definition eda_item.h:50
Helper functions to substitute paths with environmental variables.
PROJECT & Prj()
Definition kicad.cpp:730
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:170
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_FIELD_T
Definition typeinfo.h:147
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_PIN_T
Definition typeinfo.h:150
Definition of file extensions used in Kicad.