KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_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 <board_commit.h>
23#include <design_block.h>
25#include <footprint.h>
26#include <pad.h>
27#include <pcb_generator.h>
28#include <pcb_group.h>
30#include <pcb_edit_frame.h>
31#include <pcb_io/pcb_io.h>
32#include <pcb_io/pcb_io_mgr.h>
33#include <wx/choicdlg.h>
34#include <wx/msgdlg.h>
35#include <wx/textdlg.h>
37#include <paths.h>
38#include <env_paths.h>
39#include <common.h>
40#include <confirm.h>
41#include <kidialog.h>
42#include <locale_io.h>
43#include <netinfo.h>
44#include <tool/actions.h>
45#include <tool/tool_manager.h>
48#include <json_common.h>
49
50bool checkOverwriteDb( wxWindow* aFrame, wxString& libname, wxString& newName )
51{
52 wxString msg = wxString::Format( _( "Design block '%s' already exists in library '%s'." ), newName.GetData(),
53 libname.GetData() );
54
55 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing design block?" ), _( "Overwrite" ) )
56 != wxID_OK )
57 {
58 return false;
59 }
60
61 return true;
62}
63
64
65bool checkOverwriteDbLayout( wxWindow* aFrame, const LIB_ID& aLibId )
66{
67 wxString msg = wxString::Format( _( "Design block '%s' already has a layout." ), aLibId.GetUniStringLibItemName() );
68
69 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing layout?" ), _( "Overwrite" ) )
70 != wxID_OK )
71 {
72 return false;
73 }
74
75 return true;
76}
77
78
79bool PCB_EDIT_FRAME::saveBoardAsFile( BOARD& aBoard, const wxString& aFileName, bool aHeadless )
80{
81 // Ensure the "C" locale is temporary set, before saving any file
82 // It also avoid wxWidget alerts about locale issues, later, when using Python 3
84
85 wxFileName pcbFileName( aFileName );
86
87 if( !IsWritable( pcbFileName ) )
88 {
89 if( !aHeadless )
90 {
91 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
92 pcbFileName.GetFullPath() ) );
93 }
94 return false;
95 }
96
97 try
98 {
100
101 wxASSERT( pcbFileName.IsAbsolute() );
102
103 pi->SaveBoard( pcbFileName.GetFullPath(), aBoard, nullptr );
104 }
105 catch( const IO_ERROR& ioe )
106 {
107 if( !aHeadless )
108 {
109 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ), pcbFileName.GetFullPath(),
110 ioe.What() ) );
111 }
112
113 return false;
114 }
115
116 return true;
117}
118
119
120bool PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName )
121{
122 // Make sure the user has selected a library to save into
123 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
124 {
125 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
126 return false;
127 }
128
129 DESIGN_BLOCK blk;
130 wxFileName fn = wxFileNameFromPath( GetBoard()->GetFileName() );
131
132 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
133
134 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
135
136 if( dlg.ShowModal() != wxID_OK )
137 return false;
138
139 wxString libName = blk.GetLibId().GetLibNickname();
140 wxString newName = blk.GetLibId().GetLibItemName();
141
142 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
143 {
144 return false;
145 }
146
147 // Save a temporary copy of the schematic file, as the plugin is just going to move it
148 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
149
150 if( !SavePcbCopy( tempFile, false, false ) )
151 {
152 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
153 wxRemoveFile( tempFile );
154 return false;
155 }
156
157 blk.SetBoardFile( tempFile );
158
159 bool success = false;
160
161 try
162 {
163 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
165 }
166 catch( const IO_ERROR& ioe )
167 {
168 DisplayError( this, ioe.What() );
169 }
170
171 // Clean up the temporary file
172 wxRemoveFile( tempFile );
173
174 m_designBlocksPane->RefreshLibs();
175 m_designBlocksPane->SelectLibId( blk.GetLibId() );
176
177 return success;
178}
179
180
182{
183 // Make sure the user has selected a library to save into
184 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
185 {
186 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
187 return false;
188 }
189
190 wxString error;
191 std::unique_ptr<DESIGN_BLOCK> blk;
192
193 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
194 &error ) );
195
196 if( !blk )
197 {
198 DisplayErrorMessage( this, error );
199 return false;
200 }
201
202 if( !blk->GetBoardFile().IsEmpty() && !checkOverwriteDbLayout( this, aLibId ) )
203 return false;
204
205 // Save a temporary copy of the schematic file, as the plugin is just going to move it
206 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
207
208 if( !SavePcbCopy( tempFile, false, false ) )
209 {
210 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
211 wxRemoveFile( tempFile );
212 return false;
213 }
214
215 blk->SetBoardFile( tempFile );
216
217 bool success = false;
218
219 try
220 {
221 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
223 }
224 catch( const IO_ERROR& ioe )
225 {
226 DisplayError( this, ioe.What() );
227 }
228
229 // Clean up the temporary file
230 wxRemoveFile( tempFile );
231
232 m_designBlocksPane->RefreshLibs();
233 m_designBlocksPane->SelectLibId( blk->GetLibId() );
234
235 return success;
236}
237
238
239bool PCB_EDIT_FRAME::saveSelectionToDesignBlock( const wxString& aNickname, PCB_SELECTION& aSelection,
240 DESIGN_BLOCK& aBlock )
241{
242 // Create a temporary board
243 BOARD* tempBoard = new BOARD();
245 tempBoard->SetProject( &Prj(), true );
246 tempBoard->SynchronizeProperties();
247
248 // Layer names live on the BOARD, not in the design settings, so copy them over
249 for( PCB_LAYER_ID layer : GetBoard()->GetEnabledLayers().Seq() )
250 tempBoard->SetLayerName( layer, GetBoard()->GetLayerName( layer ) );
251
252 // For copying net info of selected items into the new board
253 auto addNetIfNeeded =
254 [&]( EDA_ITEM* aItem )
255 {
256 BOARD_CONNECTED_ITEM* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem );
257
258 if( cItem )
259 {
260 NETINFO_ITEM* netinfo = cItem->GetNet();
261
262 if( netinfo )
263 {
264 NETINFO_ITEM* existingInfo = tempBoard->FindNet( netinfo->GetNetname() );
265
266 // If the net has already been added to the new board, update our info to match
267 if( existingInfo )
268 cItem->SetNet( existingInfo );
269 else
270 {
271 NETINFO_ITEM* newNet = new NETINFO_ITEM( tempBoard, netinfo->GetNetname() );
272 tempBoard->Add( newNet );
273 cItem->SetNet( newNet );
274 }
275 }
276 }
277 };
278
279 auto cloneAndAdd =
280 [&] ( EDA_ITEM* aItem )
281 {
282 if( !aItem->IsBOARD_ITEM() )
283 return static_cast<BOARD_ITEM*>( nullptr );
284
285 BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( aItem->Clone() );
286 tempBoard->Add( copy, ADD_MODE::APPEND, false );
287 return copy;
288 };
289
290 // Copy the selected items to the temporary board
291 for( EDA_ITEM* item : aSelection )
292 {
293 BOARD_ITEM* copy = cloneAndAdd( item );
294
295 if( !copy )
296 continue;
297
298 copy->SetParentGroup( nullptr );
299
300 if( copy->Type() == PCB_FOOTPRINT_T )
301 {
302 static_cast<FOOTPRINT*>( copy )->RunOnChildren( addNetIfNeeded, RECURSE_MODE::NO_RECURSE );
303 }
304 else if( copy->Type() == PCB_GROUP_T || copy->Type() == PCB_GENERATOR_T )
305 {
306 // Clone() produces a shallow copy whose m_items still references original
307 // children. Replace with DeepClone() which recursively clones all children
308 // with correct group membership.
309 tempBoard->Remove( copy );
310
311 PCB_GROUP* deepCopy = nullptr;
312
313 if( item->Type() == PCB_GENERATOR_T )
314 deepCopy = static_cast<PCB_GENERATOR*>( item )->DeepClone();
315 else
316 deepCopy = static_cast<PCB_GROUP*>( item )->DeepClone();
317
318 deepCopy->SetParentGroup( nullptr );
319 tempBoard->Add( deepCopy, ADD_MODE::APPEND, false );
320
321 deepCopy->RunOnChildren(
322 [&]( BOARD_ITEM* child )
323 {
324 tempBoard->Add( child, ADD_MODE::APPEND, false );
325 addNetIfNeeded( child );
326 },
328
329 delete copy;
330 }
331 else
332 addNetIfNeeded( copy );
333 }
334
335 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
336
337 if( !saveBoardAsFile( *tempBoard, tempFile, false ) )
338 {
339 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
340 wxRemoveFile( tempFile );
341 return false;
342 }
343
344 aBlock.SetBoardFile( tempFile );
345
346 bool success = false;
347
348 try
349 {
350 success = Prj().DesignBlockLibs()->SaveDesignBlock( aNickname, &aBlock )
352 }
353 catch( const IO_ERROR& ioe )
354 {
355 DisplayError( this, ioe.What() );
356 }
357
358 // Clean up the temporary file
359 wxRemoveFile( tempFile );
360 delete tempBoard;
361
362 m_designBlocksPane->RefreshLibs();
363 m_designBlocksPane->SelectLibId( aBlock.GetLibId() );
364
365 return success;
366}
367
368
369bool PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
370{
371 // Make sure the user has selected a library to save into
372 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
373 {
374 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
375 return false;
376 }
377
378 // Get all selected items
379 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
380
381 if( selection.Empty() )
382 {
383 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
384 return false;
385 }
386
387 DESIGN_BLOCK blk;
388 PCB_GROUP* group = nullptr;
389
390 if( selection.Size() == 1 && selection.HasType( PCB_GROUP_T ) )
391 group = static_cast<PCB_GROUP*>( selection.Front() );
392
393 if( group && !group->GetName().IsEmpty() )
394 // If the user has selected a single group, they probably want the design block named after the group
395 blk.SetLibId( LIB_ID( aLibraryName, group->GetName() ) );
396 else
397 {
398 // Otherwise, use the current screen name
399 wxFileName fn = wxFileNameFromPath( GetBoard()->GetFileName() );
400 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
401 }
402
403 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
404
405 if( dlg.ShowModal() != wxID_OK )
406 return false;
407
408 wxString libName = blk.GetLibId().GetLibNickname();
409 wxString newName = blk.GetLibId().GetLibItemName();
410
411 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
412 {
413 return false;
414 }
415
416 // If we have a single group, we want to strip the group and select the children
417 if( group )
418 {
419 selection.Remove( group );
420
421 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
422 group->RunOnChildren(
423 [&]( EDA_ITEM* aItem )
424 {
425 selection.Add( aItem );
426 },
428 }
429
430 bool success = saveSelectionToDesignBlock( libName, selection, blk );
431
432 if( success && !group )
433 {
434 BOARD_COMMIT commit( m_toolManager );
435
436 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
437 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
438 newGroup->SetDesignBlockLibId( blk.GetLibId() );
439
440 int addedCount = 0;
441
442 for( EDA_ITEM* edaItem : selection )
443 {
444 if( !edaItem->IsBOARD_ITEM() )
445 continue;
446
447 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
448
449 if( item->GetParentFootprint() )
450 continue;
451
452 if( !item->IsGroupableType() )
453 continue;
454
455 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
456 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
457
458 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
459 newGroup->AddItem( item );
460 addedCount++;
461 }
462
463 if( addedCount > 0 )
464 {
465 commit.Add( newGroup );
466 commit.Push( _( "Group Items" ) );
467
469 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
470 }
471 else
472 {
473 newGroup->RemoveAll();
474 delete newGroup;
475 }
476 }
477
478 if( success && group && !group->HasDesignBlockLink() )
479 {
480 BOARD_COMMIT commit( m_toolManager );
481
482 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
483 group->SetDesignBlockLibId( blk.GetLibId() );
484
485 commit.Push( _( "Set Group Design Block Link" ) );
486 }
487
488 return success;
489}
490
491
493{
494 // Make sure the user has selected a library to save into
495 if( !aLibId.IsValid() )
496 {
497 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
498 return false;
499 }
500
501 // Get all selected items
502 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
503
504 if( selection.Empty() )
505 {
506 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
507 return false;
508 }
509
510 // If the selection is a single group, or contains this block's linked group plus extra items,
511 // we want to strip the group and select the children
512 PCB_GROUP* group = nullptr;
513 std::vector<BOARD_ITEM*> extraItems;
514
515 if( selection.Size() == 1 )
516 {
517 EDA_ITEM* item = selection.Front();
518
519 if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
520 group = static_cast<PCB_GROUP*>( item );
521 }
522 else
523 {
524 std::vector<PCB_GROUP*> linkedGroups;
525
526 for( EDA_ITEM* item : selection )
527 {
528 if( item->Type() == PCB_GROUP_T && static_cast<PCB_GROUP*>( item )->GetDesignBlockLibId() == aLibId )
529 linkedGroups.push_back( static_cast<PCB_GROUP*>( item ) );
530 }
531
532 if( linkedGroups.size() > 1 )
533 {
534 DisplayErrorMessage( this, _( "The selection contains more than one group linked to "
535 "this design block." ) );
536 return false;
537 }
538
539 if( !linkedGroups.empty() )
540 group = linkedGroups.front();
541 }
542
543 if( group )
544 {
545 for( EDA_ITEM* item : selection )
546 {
547 if( item != group && item->IsBOARD_ITEM() )
548 extraItems.push_back( static_cast<BOARD_ITEM*>( item ) );
549 }
550
551 selection.Remove( group );
552
553 // Don't recurse. If we have a group of groups the user probably intends the inner groups to be saved.
554 group->RunOnChildren(
555 [&]( EDA_ITEM* aItem )
556 {
557 selection.Add( aItem );
558 },
560 }
561
562 wxString error;
563 std::unique_ptr<DESIGN_BLOCK> blk;
564
565 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
566 &error ) );
567
568 if( !blk )
569 {
570 DisplayErrorMessage( this, error );
571 return false;
572 }
573
574 if( !blk->GetBoardFile().IsEmpty() && !checkOverwriteDbLayout( this, aLibId ) )
575 return false;
576
577 if( !saveSelectionToDesignBlock( aLibId.GetLibNickname(), selection, *blk ) )
578 return false;
579
580 // If we had a group, extend it with the extra items and reselect it
581 if( group )
582 {
583 selection.Clear();
584 selection.Add( group );
585
586 BOARD_COMMIT commit( m_toolManager );
587 bool changed = false;
588
589 for( BOARD_ITEM* item : extraItems )
590 {
591 if( item->GetParentFootprint() || !item->IsGroupableType() )
592 continue;
593
594 if( item->GetParentGroup() == group )
595 continue;
596
597 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
598 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
599
600 if( !changed )
601 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
602
603 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
604 group->AddItem( item );
605 changed = true;
606 }
607
608 // If we didn't have a design block link before, add one for convenience
609 if( !group->HasDesignBlockLink() )
610 {
611 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
612 group->SetDesignBlockLibId( aLibId );
613 changed = true;
614 }
615
616 if( changed )
617 commit.Push( _( "Update Design Block Group" ) );
618 }
619 else
620 {
621 BOARD_COMMIT commit( m_toolManager );
622
623 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
624 newGroup->SetName( aLibId.GetUniStringLibItemName() );
625 newGroup->SetDesignBlockLibId( aLibId );
626
627 int addedCount = 0;
628
629 for( EDA_ITEM* edaItem : selection )
630 {
631 if( !edaItem->IsBOARD_ITEM() )
632 continue;
633
634 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
635
636 if( item->GetParentFootprint() )
637 continue;
638
639 if( !item->IsGroupableType() )
640 continue;
641
642 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
643 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
644
645 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
646 newGroup->AddItem( item );
647 addedCount++;
648 }
649
650 if( addedCount > 0 )
651 {
652 commit.Add( newGroup );
653 commit.Push( _( "Group Items" ) );
654
656 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
657 }
658 else
659 {
660 newGroup->RemoveAll();
661 delete newGroup;
662 }
663 }
664
665 return true;
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
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
NETINFO_ITEM * GetNet() const
Return NETINFO_ITEM object for a given item.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
bool IsGroupableType() const
FOOTPRINT * GetParentFootprint() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1524
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:3001
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
Definition board.cpp:1307
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:961
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:377
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:3153
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1695
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 SetBoardFile(const wxString &aFile)
void SetLibId(const LIB_ID &aName)
const LIB_ID & GetLibId() const
int ShowModal() override
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:43
const LIB_ID & GetDesignBlockLibId() const
Definition eda_group.h:102
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 SetParentGroup(EDA_GROUP *aGroup)
Definition eda_item.h:115
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
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
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
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Handle the data for a net.
Definition netinfo.h:50
const wxString & GetNetname() const
Definition netinfo.h:110
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
bool saveBoardAsFile(BOARD &aBoard, const wxString &aFileName, bool aHeadless=false)
Save a board object to a file.
bool saveSelectionToDesignBlock(const wxString &aNickname, PCB_SELECTION &aSelection, DESIGN_BLOCK &aBlock)
bool UpdateDesignBlockFromBoard(const LIB_ID &aLibId)
bool UpdateDesignBlockFromSelection(const LIB_ID &aLibId)
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false, bool aHeadless=false)
Write the board data structures to aFileName.
bool SaveSelectionAsDesignBlock(const wxString &aLibraryName)
bool SaveBoardAsDesignBlock(const wxString &aLibraryName)
PCB_DESIGN_BLOCK_PANE * m_designBlocksPane
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:51
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
EDA_ITEM * AsEdaItem() override
Definition pcb_group.h:59
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a PCB_IO which the caller can use to import, export, save, or load design documents.
The selection tool: currently supports:
virtual DESIGN_BLOCK_LIBRARY_ADAPTER * DesignBlockLibs()
Return the table of design block libraries.
Definition project.cpp:433
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.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
PROJECT & Prj()
Definition kicad.cpp:733
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
bool checkOverwriteDb(wxWindow *aFrame, wxString &libname, wxString &newName)
bool checkOverwriteDbLayout(wxWindow *aFrame, const LIB_ID &aLibId)
Class to handle a set of BOARD_ITEMs.
see class PGM_BASE
bool checkOverwriteDb(wxWindow *aFrame, wxString &libname, wxString &newName)
std::vector< FAB_LAYER_COLOR > dummy
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:83
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:103
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:78
Definition of file extensions used in Kicad.