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
361 m_designBlocksPane->RefreshLibs();
362 m_designBlocksPane->SelectLibId( aBlock.GetLibId() );
363
364 return success;
365}
366
367
368bool PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName )
369{
370 // Make sure the user has selected a library to save into
371 if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() )
372 {
373 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
374 return false;
375 }
376
377 // Get all selected items
378 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
379
380 if( selection.Empty() )
381 {
382 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
383 return false;
384 }
385
386 DESIGN_BLOCK blk;
387 PCB_GROUP* group = nullptr;
388
389 if( selection.Size() == 1 && selection.HasType( PCB_GROUP_T ) )
390 group = static_cast<PCB_GROUP*>( selection.Front() );
391
392 if( group && !group->GetName().IsEmpty() )
393 // If the user has selected a single group, they probably want the design block named after the group
394 blk.SetLibId( LIB_ID( aLibraryName, group->GetName() ) );
395 else
396 {
397 // Otherwise, use the current screen name
398 wxFileName fn = wxFileNameFromPath( GetBoard()->GetFileName() );
399 blk.SetLibId( LIB_ID( aLibraryName, fn.GetName() ) );
400 }
401
402 DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk );
403
404 if( dlg.ShowModal() != wxID_OK )
405 return false;
406
407 wxString libName = blk.GetLibId().GetLibNickname();
408 wxString newName = blk.GetLibId().GetLibItemName();
409
410 if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) && !checkOverwriteDb( this, libName, newName ) )
411 {
412 return false;
413 }
414
415 // If we have a single group, we want to strip the group and select the children
416 if( group )
417 {
418 selection.Remove( group );
419
420 // Don't recurse; if we have a group of groups the user probably intends the inner groups to be saved
421 group->RunOnChildren(
422 [&]( EDA_ITEM* aItem )
423 {
424 selection.Add( aItem );
425 },
427 }
428
429 bool success = saveSelectionToDesignBlock( libName, selection, blk );
430
431 if( success && !group )
432 {
433 BOARD_COMMIT commit( m_toolManager );
434
435 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
436 newGroup->SetName( blk.GetLibId().GetUniStringLibItemName() );
437 newGroup->SetDesignBlockLibId( blk.GetLibId() );
438
439 int addedCount = 0;
440
441 for( EDA_ITEM* edaItem : selection )
442 {
443 if( !edaItem->IsBOARD_ITEM() )
444 continue;
445
446 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
447
448 if( item->GetParentFootprint() )
449 continue;
450
451 if( !item->IsGroupableType() )
452 continue;
453
454 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
455 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
456
457 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
458 newGroup->AddItem( item );
459 addedCount++;
460 }
461
462 if( addedCount > 0 )
463 {
464 commit.Add( newGroup );
465 commit.Push( _( "Group Items" ) );
466
468 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
469 }
470 else
471 {
472 newGroup->RemoveAll();
473 delete newGroup;
474 }
475 }
476
477 if( success && group && !group->HasDesignBlockLink() )
478 {
479 BOARD_COMMIT commit( m_toolManager );
480
481 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
482 group->SetDesignBlockLibId( blk.GetLibId() );
483
484 commit.Push( _( "Set Group Design Block Link" ) );
485 }
486
487 return success;
488}
489
490
492{
493 // Make sure the user has selected a library to save into
494 if( !aLibId.IsValid() )
495 {
496 DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) );
497 return false;
498 }
499
500 // Get all selected items
501 PCB_SELECTION selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
502
503 if( selection.Empty() )
504 {
505 DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) );
506 return false;
507 }
508
509 // If the selection is a single group, or contains this block's linked group plus extra items,
510 // we want to strip the group and select the children
511 PCB_GROUP* group = nullptr;
512 std::vector<BOARD_ITEM*> extraItems;
513
514 if( selection.Size() == 1 )
515 {
516 EDA_ITEM* item = selection.Front();
517
518 if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
519 group = static_cast<PCB_GROUP*>( item );
520 }
521 else
522 {
523 std::vector<PCB_GROUP*> linkedGroups;
524
525 for( EDA_ITEM* item : selection )
526 {
527 if( item->Type() == PCB_GROUP_T && static_cast<PCB_GROUP*>( item )->GetDesignBlockLibId() == aLibId )
528 linkedGroups.push_back( static_cast<PCB_GROUP*>( item ) );
529 }
530
531 if( linkedGroups.size() > 1 )
532 {
533 DisplayErrorMessage( this, _( "The selection contains more than one group linked to "
534 "this design block." ) );
535 return false;
536 }
537
538 if( !linkedGroups.empty() )
539 group = linkedGroups.front();
540 }
541
542 if( group )
543 {
544 for( EDA_ITEM* item : selection )
545 {
546 if( item != group && item->IsBOARD_ITEM() )
547 extraItems.push_back( static_cast<BOARD_ITEM*>( item ) );
548 }
549
550 selection.Remove( group );
551
552 // Don't recurse. If we have a group of groups the user probably intends the inner groups to be saved.
553 group->RunOnChildren(
554 [&]( EDA_ITEM* aItem )
555 {
556 selection.Add( aItem );
557 },
559 }
560
561 wxString error;
562 std::unique_ptr<DESIGN_BLOCK> blk;
563
564 blk.reset( Prj().DesignBlockLibs()->LoadDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false,
565 &error ) );
566
567 if( !blk )
568 {
569 DisplayErrorMessage( this, error );
570 return false;
571 }
572
573 if( !blk->GetBoardFile().IsEmpty() && !checkOverwriteDbLayout( this, aLibId ) )
574 return false;
575
576 if( !saveSelectionToDesignBlock( aLibId.GetLibNickname(), selection, *blk ) )
577 return false;
578
579 // If we had a group, extend it with the extra items and reselect it
580 if( group )
581 {
582 selection.Clear();
583 selection.Add( group );
584
585 BOARD_COMMIT commit( m_toolManager );
586 bool changed = false;
587
588 for( BOARD_ITEM* item : extraItems )
589 {
590 if( item->GetParentFootprint() || !item->IsGroupableType() )
591 continue;
592
593 if( item->GetParentGroup() == group )
594 continue;
595
596 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
597 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
598
599 if( !changed )
600 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
601
602 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
603 group->AddItem( item );
604 changed = true;
605 }
606
607 // If we didn't have a design block link before, add one for convenience
608 if( !group->HasDesignBlockLink() )
609 {
610 commit.Modify( group, nullptr, RECURSE_MODE::NO_RECURSE );
611 group->SetDesignBlockLibId( aLibId );
612 changed = true;
613 }
614
615 if( changed )
616 commit.Push( _( "Update Design Block Group" ) );
617 }
618 else
619 {
620 BOARD_COMMIT commit( m_toolManager );
621
622 PCB_GROUP* newGroup = new PCB_GROUP( GetBoard() );
623 newGroup->SetName( aLibId.GetUniStringLibItemName() );
624 newGroup->SetDesignBlockLibId( aLibId );
625
626 int addedCount = 0;
627
628 for( EDA_ITEM* edaItem : selection )
629 {
630 if( !edaItem->IsBOARD_ITEM() )
631 continue;
632
633 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
634
635 if( item->GetParentFootprint() )
636 continue;
637
638 if( !item->IsGroupableType() )
639 continue;
640
641 if( EDA_GROUP* existingGroup = item->GetParentGroup() )
642 commit.Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
643
644 commit.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
645 newGroup->AddItem( item );
646 addedCount++;
647 }
648
649 if( addedCount > 0 )
650 {
651 commit.Add( newGroup );
652 commit.Push( _( "Group Items" ) );
653
655 m_toolManager->RunAction( ACTIONS::selectItem, newGroup->AsEdaItem() );
656 }
657 else
658 {
659 newGroup->RemoveAll();
660 delete newGroup;
661 }
662 }
663
664 return true;
665}
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
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,...
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
NETINFO_ITEM * GetNet() const
Return #NET_INFO 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:409
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1497
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:2980
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
Definition board.cpp:1305
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:954
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:374
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:3132
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1668
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:88
void RemoveAll()
Definition eda_group.cpp:86
void SetDesignBlockLibId(const LIB_ID &aLibId)
Definition eda_group.h:87
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:58
void SetName(const wxString &aName)
Definition eda_group.h:62
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual void 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 #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: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:727
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.