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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <pgm_base.h>
25#include <kiway.h>
26#include <board_commit.h>
27#include <design_block.h>
29#include <footprint.h>
30#include <pad.h>
31#include <pcb_generator.h>
32#include <pcb_group.h>
34#include <pcb_edit_frame.h>
35#include <pcb_io/pcb_io.h>
36#include <pcb_io/pcb_io_mgr.h>
37#include <wx/choicdlg.h>
38#include <wx/msgdlg.h>
39#include <wx/textdlg.h>
41#include <paths.h>
42#include <env_paths.h>
43#include <common.h>
44#include <confirm.h>
45#include <kidialog.h>
46#include <locale_io.h>
47#include <netinfo.h>
48#include <tool/actions.h>
49#include <tool/tool_manager.h>
52#include <json_common.h>
53
54bool checkOverwriteDb( wxWindow* aFrame, wxString& libname, wxString& newName )
55{
56 wxString msg = wxString::Format( _( "Design block '%s' already exists in library '%s'." ), newName.GetData(),
57 libname.GetData() );
58
59 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing design block?" ), _( "Overwrite" ) )
60 != wxID_OK )
61 {
62 return false;
63 }
64
65 return true;
66}
67
68
69bool checkOverwriteDbLayout( wxWindow* aFrame, const LIB_ID& aLibId )
70{
71 wxString msg = wxString::Format( _( "Design block '%s' already has a layout." ), aLibId.GetUniStringLibItemName() );
72
73 if( OKOrCancelDialog( aFrame, _( "Confirmation" ), msg, _( "Overwrite existing layout?" ), _( "Overwrite" ) )
74 != wxID_OK )
75 {
76 return false;
77 }
78
79 return true;
80}
81
82
83bool PCB_EDIT_FRAME::saveBoardAsFile( BOARD* aBoard, const wxString& aFileName, bool aHeadless )
84{
85 // Ensure the "C" locale is temporary set, before saving any file
86 // It also avoid wxWidget alerts about locale issues, later, when using Python 3
88
89 wxFileName pcbFileName( aFileName );
90
91 if( !IsWritable( pcbFileName ) )
92 {
93 if( !aHeadless )
94 {
95 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
96 pcbFileName.GetFullPath() ) );
97 }
98 return false;
99 }
100
101 try
102 {
104
105 wxASSERT( pcbFileName.IsAbsolute() );
106
107 pi->SaveBoard( pcbFileName.GetFullPath(), aBoard, nullptr );
108 }
109 catch( const IO_ERROR& ioe )
110 {
111 if( !aHeadless )
112 {
113 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ), pcbFileName.GetFullPath(),
114 ioe.What() ) );
115 }
116
117 return false;
118 }
119
120 return true;
121}
122
123
124bool PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName )
125{
126 // Make sure the user has selected a library to save into
127 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
128 {
129 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
130 return false;
131 }
132
133 DESIGN_BLOCK blk;
134 wxFileName fn = wxFileNameFromPath( GetBoard()->GetFileName() );
135
136 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
137
138 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
139
140 if( dlg.ShowModal() != wxID_OK )
141 return false;
142
143 wxString libName = blk.GetLibId().GetLibNickname();
144 wxString newName = blk.GetLibId().GetLibItemName();
145
146 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
147 {
148 return false;
149 }
150
151 // Save a temporary copy of the schematic file, as the plugin is just going to move it
152 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
153
154 if( !SavePcbCopy( tempFile, false, false ) )
155 {
156 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
157 wxRemoveFile( tempFile );
158 return false;
159 }
160
161 blk.SetBoardFile( tempFile );
162
163 bool success = false;
164
165 try
166 {
167 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibraryName, &blk )
169 }
170 catch( const IO_ERROR& ioe )
171 {
172 DisplayError( this, ioe.What() );
173 }
174
175 // Clean up the temporary file
176 wxRemoveFile( tempFile );
177
178 m_designBlocksPane->RefreshLibs();
179 m_designBlocksPane->SelectLibId( blk.GetLibId() );
180
181 return success;
182}
183
184
186{
187 // Make sure the user has selected a library to save into
188 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
189 {
190 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
191 return false;
192 }
193
194 std::unique_ptr<DESIGN_BLOCK> blk;
195
196 try
197 {
198 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) );
199 }
200 catch( const IO_ERROR& ioe )
201 {
202 DisplayError( this, ioe.What() );
203 return false;
204 }
205
206 if( !blk )
207 {
209 this, wxString::Format( _( "Design block '%s' does not exist." ), aLibId.GetUniStringLibItemName() ) );
210 return false;
211 }
212
213 if( !blk->GetBoardFile().IsEmpty() && !checkOverwriteDbLayout( this, aLibId ) )
214 return false;
215
216 // Save a temporary copy of the schematic file, as the plugin is just going to move it
217 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
218
219 if( !SavePcbCopy( tempFile, false, false ) )
220 {
221 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
222 wxRemoveFile( tempFile );
223 return false;
224 }
225
226 blk->SetBoardFile( tempFile );
227
228 bool success = false;
229
230 try
231 {
232 success = Prj().DesignBlockLibs()->SaveDesignBlock( aLibId.GetLibNickname(), blk.get() )
234 }
235 catch( const IO_ERROR& ioe )
236 {
237 DisplayError( this, ioe.What() );
238 }
239
240 // Clean up the temporary file
241 wxRemoveFile( tempFile );
242
243 m_designBlocksPane->RefreshLibs();
244 m_designBlocksPane->SelectLibId( blk->GetLibId() );
245
246 return success;
247}
248
249
250bool PCB_EDIT_FRAME::saveSelectionToDesignBlock( const wxString& aNickname, PCB_SELECTION& aSelection,
251 DESIGN_BLOCK& aBlock )
252{
253 // Create a temporary board
254 BOARD* tempBoard = new BOARD();
256 tempBoard->SetProject( &Prj(), true );
257 tempBoard->SynchronizeProperties();
258
259 // For copying net info of selected items into the new board
260 auto addNetIfNeeded =
261 [&]( EDA_ITEM* aItem )
262 {
263 BOARD_CONNECTED_ITEM* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem );
264
265 if( cItem )
266 {
267 NETINFO_ITEM* netinfo = cItem->GetNet();
268
269 if( netinfo )
270 {
271 NETINFO_ITEM* existingInfo = tempBoard->FindNet( netinfo->GetNetname() );
272
273 // If the net has already been added to the new board, update our info to match
274 if( existingInfo )
275 cItem->SetNet( existingInfo );
276 else
277 {
278 NETINFO_ITEM* newNet = new NETINFO_ITEM( tempBoard, netinfo->GetNetname() );
279 tempBoard->Add( newNet );
280 cItem->SetNet( newNet );
281 }
282 }
283 }
284 };
285
286 auto cloneAndAdd =
287 [&] ( EDA_ITEM* aItem )
288 {
289 if( !aItem->IsBOARD_ITEM() )
290 return static_cast<BOARD_ITEM*>( nullptr );
291
292 BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( aItem->Clone() );
293 tempBoard->Add( copy, ADD_MODE::APPEND, false );
294 return copy;
295 };
296
297 // Copy the selected items to the temporary board
298 for( EDA_ITEM* item : aSelection )
299 {
300 BOARD_ITEM* copy = cloneAndAdd( item );
301
302 if( !copy )
303 continue;
304
305 copy->SetParentGroup( nullptr );
306
307 if( copy->Type() == PCB_FOOTPRINT_T )
308 {
309 static_cast<FOOTPRINT*>( copy )->RunOnChildren( addNetIfNeeded, RECURSE_MODE::NO_RECURSE );
310 }
311 else if( copy->Type() == PCB_GROUP_T || copy->Type() == PCB_GENERATOR_T )
312 {
313 // Clone() produces a shallow copy whose m_items still references original
314 // children. Replace with DeepClone() which recursively clones all children
315 // with correct group membership.
316 tempBoard->Remove( copy );
317
318 PCB_GROUP* deepCopy = nullptr;
319
320 if( item->Type() == PCB_GENERATOR_T )
321 deepCopy = static_cast<PCB_GENERATOR*>( item )->DeepClone();
322 else
323 deepCopy = static_cast<PCB_GROUP*>( item )->DeepClone();
324
325 deepCopy->SetParentGroup( nullptr );
326 tempBoard->Add( deepCopy, ADD_MODE::APPEND, false );
327
328 deepCopy->RunOnChildren(
329 [&]( BOARD_ITEM* child )
330 {
331 tempBoard->Add( child, ADD_MODE::APPEND, false );
332 addNetIfNeeded( child );
333 },
335
336 delete copy;
337 }
338 else
339 addNetIfNeeded( copy );
340 }
341
342 wxString tempFile = wxFileName::CreateTempFileName( "design_block" );
343
344 if( !saveBoardAsFile( tempBoard, tempFile, false ) )
345 {
346 DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) );
347 wxRemoveFile( tempFile );
348 return false;
349 }
350
351 aBlock.SetBoardFile( tempFile );
352
353 bool success = false;
354
355 try
356 {
357 success = Prj().DesignBlockLibs()->SaveDesignBlock( aNickname, &aBlock )
359 }
360 catch( const IO_ERROR& ioe )
361 {
362 DisplayError( this, ioe.What() );
363 }
364
365 // Clean up the temporary file
366 wxRemoveFile( tempFile );
367
368 m_designBlocksPane->RefreshLibs();
369 m_designBlocksPane->SelectLibId( aBlock.GetLibId() );
370
371 return success;
372}
373
374
375bool PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
376{
377 // Make sure the user has selected a library to save into
378 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
379 {
380 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
381 return false;
382 }
383
384 // Get all selected items
385 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
386
387 if( selection.Empty() )
388 {
389 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
390 return false;
391 }
392
393 DESIGN_BLOCK blk;
394 PCB_GROUP* group = nullptr;
395
396 if( selection.Size() == 1 && selection.HasType( PCB_GROUP_T ) )
397 group = static_cast<PCB_GROUP*>( selection.Front() );
398
399 if( group && !group->GetName().IsEmpty() )
400 // If the user has selected a single group, they probably want the design block named after the group
401 blk.SetLibId( LIB_ID( aLibraryName, group->GetName() ) );
402 else
403 {
404 // Otherwise, use the current screen name
405 wxFileName fn = wxFileNameFromPath( GetBoard()->GetFileName() );
406 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
407 }
408
409 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
410
411 if( dlg.ShowModal() != wxID_OK )
412 return false;
413
414 wxString libName = blk.GetLibId().GetLibNickname();
415 wxString newName = blk.GetLibId().GetLibItemName();
416
417 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
418 {
419 return false;
420 }
421
422 // If we have a single group, we want to strip the group and select the children
423 if( group )
424 {
425 selection.Remove( group );
426
427 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
428 group->RunOnChildren(
429 [&]( EDA_ITEM* aItem )
430 {
431 selection.Add( aItem );
432 },
434 }
435
436 bool success = saveSelectionToDesignBlock( libName, selection, blk );
437
438 if( success && !group )
439 {
440 BOARD_COMMIT commit( m_toolManager );
441
442 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
443 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
444 newGroup->SetDesignBlockLibId( blk.GetLibId() );
445
446 int addedCount = 0;
447
448 for( EDA_ITEM* edaItem : selection )
449 {
450 if( !edaItem->IsBOARD_ITEM() )
451 continue;
452
453 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
454
455 if( item->GetParentFootprint() )
456 continue;
457
458 if( !item->IsGroupableType() )
459 continue;
460
461 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
462 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
463
464 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
465 newGroup->AddItem( item );
466 addedCount++;
467 }
468
469 if( addedCount > 0 )
470 {
471 commit.Add( newGroup );
472 commit.Push( _( "Group Items" ) );
473
475 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
476 }
477 else
478 {
479 newGroup->RemoveAll();
480 delete newGroup;
481 }
482 }
483
484 if( success && group && !group->HasDesignBlockLink() )
485 {
486 BOARD_COMMIT commit( m_toolManager );
487
488 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
489 group->SetDesignBlockLibId( blk.GetLibId() );
490
491 commit.Push( _( "Set Group Design Block Link" ) );
492 }
493
494 return success;
495}
496
497
499{
500 // Make sure the user has selected a library to save into
501 if( !aLibId.IsValid() )
502 {
503 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
504 return false;
505 }
506
507 // Get all selected items
508 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
509
510 if( selection.Empty() )
511 {
512 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
513 return false;
514 }
515
516 // If we have a single group, we want to strip the group and select the children
517 PCB_GROUP* group = nullptr;
518
519 if( selection.Size() == 1 )
520 {
521 EDA_ITEM* item = selection.Front();
522
523 if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
524 {
525 group = static_cast<PCB_GROUP*>( item );
526
527 selection.Remove( item );
528
529 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
530 group->RunOnChildren( [&]( EDA_ITEM* aItem ) { selection.Add( aItem ); }, RECURSE_MODE::NO_RECURSE );
531 }
532 }
533
534 std::unique_ptr<DESIGN_BLOCK> blk;
535
536 try
537 {
538 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() ) );
539 }
540 catch( const IO_ERROR& ioe )
541 {
542 DisplayError( this, ioe.What() );
543 return false;
544 }
545
546 if( !blk )
547 {
549 this, wxString::Format( _( "Design block '%s' does not exist." ), aLibId.GetUniStringLibItemName() ) );
550 return false;
551 }
552
553 if( !blk->GetBoardFile().IsEmpty() && !checkOverwriteDbLayout( this, aLibId ) )
554 return false;
555
556 if( !saveSelectionToDesignBlock( aLibId.GetLibNickname(), selection, *blk ) )
557 return false;
558
559 // If we had a group, we need to reselect it
560 if( group )
561 {
562 selection.Clear();
563 selection.Add( group );
564
565 // If we didn't have a design block link before, add one for convenience
566 if( !group->HasDesignBlockLink() )
567 {
568 BOARD_COMMIT commit( m_toolManager );
569
570 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
571 group->SetDesignBlockLibId( aLibId );
572
573 commit.Push( _( "Set Group Design Block Link" ) );
574 }
575 }
576 else
577 {
578 BOARD_COMMIT commit( m_toolManager );
579
580 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
581 newGroup->SetName( aLibId.GetUniStringLibItemName() );
582 newGroup->SetDesignBlockLibId( aLibId );
583
584 int addedCount = 0;
585
586 for( EDA_ITEM* edaItem : selection )
587 {
588 if( !edaItem->IsBOARD_ITEM() )
589 continue;
590
591 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
592
593 if( item->GetParentFootprint() )
594 continue;
595
596 if( !item->IsGroupableType() )
597 continue;
598
599 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
600 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
601
602 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
603 newGroup->AddItem( item );
604 addedCount++;
605 }
606
607 if( addedCount > 0 )
608 {
609 commit.Add( newGroup );
610 commit.Push( _( "Group Items" ) );
611
613 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
614 }
615 else
616 {
617 newGroup->RemoveAll();
618 delete newGroup;
619 }
620 }
621
622 return true;
623}
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:227
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:224
virtual 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,...
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the 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:322
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1223
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:2375
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
Definition board.cpp:1089
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:201
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:2495
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1382
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:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
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:46
void RemoveAll()
Definition eda_group.cpp:49
void SetDesignBlockLibId(const LIB_ID &aLibId)
Definition eda_group.h:72
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:27
void SetName(const wxString &aName)
Definition eda_group.h:52
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:99
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:117
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition eda_item.h:116
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:49
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:172
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition lib_id.h:112
const UTF8 & GetLibItemName() const
Definition lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:87
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
Handle the data for a net.
Definition netinfo.h:54
const wxString & GetNetname() const
Definition netinfo.h:112
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:53
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:60
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:58
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN 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:427
virtual void Add(EDA_ITEM *aItem)
Definition selection.cpp:42
virtual void Remove(EDA_ITEM *aItem)
Definition selection.cpp:60
EDA_ITEM * Front() const
Definition selection.h:177
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:98
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:121
bool Empty() const
Checks if there is anything selected.
Definition selection.h:115
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:150
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
#define _(s)
@ RECURSE
Definition eda_item.h:52
@ NO_RECURSE
Definition eda_item.h:53
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:642
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:91
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:111
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:86
Definition of file extensions used in Kicad.