KiCad PCB EDA Suite
Loading...
Searching...
No Matches
footprint_editor_control.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 (C) 2014-2019 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
23
24#include <memory>
25
26#include <advanced_config.h>
27#include <string_utils.h>
28#include <pgm_base.h>
30#include <tool/tool_manager.h>
32#include <tools/pcb_actions.h>
34#include <eda_doc.h>
37#include <pcbnew_settings.h>
38#include <pcbnew_id.h>
39#include <confirm.h>
40#include <kidialog.h>
41#include <wx/debug.h>
42#include <wx/filedlg.h>
43#include <wx/filename.h>
45#include <launch_ext.h> // To default when file manager setting is empty
46#include <gestfich.h> // To open with a text editor
47#include <widgets/wx_infobar.h>
48#include <footprint.h>
49#include <pad.h>
50#include <pcb_group.h>
51#include <zone.h>
58#include <kiway.h>
59#include <pcb_plotter.h>
60#include <project_pcb.h>
61#include <view/view_controls.h>
66#include <wx/dirdlg.h>
67
68
70 PCB_TOOL_BASE( "pcbnew.ModuleEditor" ),
71 m_frame( nullptr ),
72 m_checkerDialog( nullptr )
73{
74}
75
76
84
85
87{
88 LIBRARY_EDITOR_CONTROL* libraryTreeTool = m_toolMgr->GetTool<LIBRARY_EDITOR_CONTROL>();
89
90 // Build a context menu for the footprint tree
91 //
92 CONDITIONAL_MENU& ctxMenu = m_menu->GetMenu();
93
94 auto libSelectedCondition =
95 [this]( const SELECTION& aSel )
96 {
97 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
98 return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
99 };
100
101 // The libInferredCondition allows you to do things like New Symbol and Paste with a
102 // symbol selected (in other words, when we know the library context even if the library
103 // itself isn't selected.
104 auto libInferredCondition =
105 [this]( const SELECTION& aSel )
106 {
107 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
108 return !sel.GetLibNickname().empty();
109 };
110
111 auto fpSelectedCondition =
112 [this]( const SELECTION& aSel )
113 {
114 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
115 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
116 };
117
118 auto fpExportCondition =
119 [this]( const SELECTION& aSel )
120 {
121 FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
122 return fp != nullptr;
123 };
124
125 auto canOpenExternally =
126 [this]( const SELECTION& aSel )
127 {
128 // The option is shown if the editor has no current edits,
129 // dumb/simple guard against opening a new file that does not exist on disk
130 bool ret = !m_frame->IsContentModified();
131 return ret;
132 };
133
134// clang-format off
135 ctxMenu.AddItem( PCB_ACTIONS::newFootprint, libSelectedCondition, 10 );
136 ctxMenu.AddItem( PCB_ACTIONS::createFootprint, libSelectedCondition, 10 );
137
138 ctxMenu.AddSeparator( 10 );
139 ctxMenu.AddItem( ACTIONS::save, SELECTION_CONDITIONS::ShowAlways, 10 );
140 ctxMenu.AddItem( ACTIONS::saveAs, libSelectedCondition || fpSelectedCondition, 10 );
141 ctxMenu.AddItem( ACTIONS::revert, libSelectedCondition || libInferredCondition, 10 );
142
143 ctxMenu.AddSeparator( 10 );
144 ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition, 10 );
145 ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition, 10 );
146 ctxMenu.AddItem( PCB_ACTIONS::pasteFootprint, libInferredCondition, 10 );
147 ctxMenu.AddItem( PCB_ACTIONS::duplicateFootprint, fpSelectedCondition, 10 );
148 ctxMenu.AddItem( PCB_ACTIONS::renameFootprint, fpSelectedCondition, 10 );
149 ctxMenu.AddItem( PCB_ACTIONS::deleteFootprint, fpSelectedCondition, 10 );
150 ctxMenu.AddItem( PCB_ACTIONS::footprintProperties, fpSelectedCondition, 10 );
151
152 ctxMenu.AddSeparator( 100 );
153 ctxMenu.AddItem( PCB_ACTIONS::importFootprint, libInferredCondition, 100 );
154 ctxMenu.AddItem( PCB_ACTIONS::exportFootprint, fpExportCondition, 100 );
155
156 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText )
157 {
158 ctxMenu.AddSeparator( 200 );
159 ctxMenu.AddItem( ACTIONS::openWithTextEditor, canOpenExternally && fpSelectedCondition, 200 );
160 }
161
162 if( ADVANCED_CFG::GetCfg().m_EnableLibDir )
163 {
164 ctxMenu.AddSeparator( 200 );
165 ctxMenu.AddItem( ACTIONS::openDirectory, canOpenExternally && ( libSelectedCondition || fpSelectedCondition ), 200 );
166 }
167
168 ctxMenu.AddSeparator( 300 );
169 ctxMenu.AddItem( PCB_ACTIONS::showLibFootprintFieldsTable, libInferredCondition, 300 );
170// clang-format on
171
172 libraryTreeTool->AddContextMenuItems( &ctxMenu );
173
174 // Ensure the left toolbar's Line modes group reflects the current setting at startup
175 if( m_toolMgr )
177
178 return true;
179}
180
181
183 const LIB_ID& aTargetLib )
184{
185 const wxString libraryName = aTargetLib.GetUniStringLibNickname();
186
187 if( aTargetLib.GetLibNickname().empty() )
188 {
189 // Do nothing - the footprint will need to be saved manually to assign
190 // to a library.
191 }
192 else
193 {
194 if( !PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->IsFootprintLibWritable( libraryName ) )
195 {
196 // If the library is not writeable, we'll give the user a
197 // footprint not in a library. But add a warning to let them know
198 // they didn't quite get what they wanted.
199 m_frame->ShowInfoBarWarning(
200 wxString::Format(
201 _( "The footprint could not be added to the selected library ('%s'). "
202 "This library is read-only." ),
203 libraryName ),
204 false );
205 // And the footprint will need to be saved manually
206 }
207 else
208 {
209 // Go ahead and save it to the library
210 LIB_ID fpid = aFootprint.GetFPID();
211 fpid.SetLibNickname( aTargetLib.GetLibNickname() );
212 aFootprint.SetFPID( fpid );
213
214 // Clear the modified flag only on a successful save, else the edits are silently
215 // lost (issue #23850).
216 if( m_frame->SaveFootprint( &aFootprint ) )
217 m_frame->ClearModify();
218 }
219 }
220}
221
222
224{
225 const LIB_ID selected = m_frame->GetTargetFPID();
226 const wxString libraryName = selected.GetUniStringLibNickname();
227
228 if( !m_frame->BeginNewFootprint( libraryName ) )
229 return 0;
230
231 FOOTPRINT* newFootprint = m_frame->CreateNewFootprint( wxEmptyString, libraryName );
232
233 if( !newFootprint )
234 return 0;
235
236 // Give the new footprint a resolvable identity so it opens in its own tab instead of
237 // overwriting the active one.
238 if( !libraryName.IsEmpty() )
239 {
240 newFootprint->SetFPID( LIB_ID( libraryName, newFootprint->GetFPID().GetLibItemName() ) );
241 }
242 else
243 {
244 newFootprint->SetParent( nullptr );
245 m_frame->CreateUnsavedFootprintTab();
246 }
247
249 m_frame->AddFootprintToBoard( newFootprint );
250
251 // Initialize data relative to nets and netclasses (for a new footprint the defaults are
252 // used). This is mandatory to handle and draw pads.
254 newFootprint->SetPosition( VECTOR2I( 0, 0 ) );
255 newFootprint->ClearFlags();
256
257 m_frame->Zoom_Automatique( false );
258 m_frame->GetScreen()->SetContentModified();
259 m_frame->OnModify();
260
261 tryToSaveFootprintInLibrary( *newFootprint, selected );
262
263 m_frame->UpdateView();
264 m_frame->GetCanvas()->ForceRefresh();
265 m_frame->Update3DView( true, true );
266
267 m_frame->SyncLibraryTree( false );
268 return 0;
269}
270
271
273{
274 const LIB_ID selected = m_frame->GetTargetFPID();
275
276 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_WIZARD, true, m_frame ) )
277 {
278 FOOTPRINT_WIZARD_FRAME* wizard = static_cast<FOOTPRINT_WIZARD_FRAME*>( frame );
279
280 if( wizard->ShowModal( nullptr, m_frame ) )
281 {
282 // Creates the new footprint from python script wizard
283 FOOTPRINT* newFootprint = wizard->GetBuiltFootprint();
284
285 if( newFootprint ) // i.e. if create footprint command is OK
286 {
287 if( !m_frame->BeginNewFootprint( selected.GetLibNickname() ) )
288 {
289 delete newFootprint;
290 wizard->Destroy();
291 return 0;
292 }
293
294 newFootprint->SetParent( nullptr );
295 m_frame->CreateUnsavedFootprintTab();
296
298 // Add the new object to board
299 m_frame->AddFootprintToBoard( newFootprint );
300
301 // Initialize data relative to nets and netclasses (for a new footprint the
302 // defaults are used). This is mandatory to handle and draw pads.
304 newFootprint->SetPosition( VECTOR2I( 0, 0 ) );
305 newFootprint->ClearFlags();
306
307 m_frame->Zoom_Automatique( false );
308 m_frame->GetScreen()->SetContentModified();
309 m_frame->OnModify();
310
311 tryToSaveFootprintInLibrary( *newFootprint, selected );
312
313 m_frame->UpdateView();
314 canvas()->Refresh();
315 m_frame->Update3DView( true, true );
316
317 m_frame->SyncLibraryTree( false );
318 }
319 }
320
321 wizard->Destroy();
322 }
323
324 return 0;
325}
326
327
329{
330 if( !footprint() ) // no loaded footprint
331 return 0;
332
333 const LIB_ID loadedId = m_frame->GetLoadedFPID();
334
335 // An unsaved import has no library identity for the tree selection to match, and save-as is the only
336 // way to give it one, so never let an unrelated selection swallow its save
337 if( m_frame->GetTargetFPID() == loadedId || loadedId.GetLibNickname().empty() )
338 {
339 if( m_frame->SaveFootprint( footprint() ) )
340 {
341 view()->Update( footprint() );
342
343 canvas()->ForceRefresh();
344 m_frame->ClearModify();
345 }
346 }
347
348 m_frame->RefreshLibraryTree();
349 return 0;
350}
351
352
354{
355 if( m_frame->GetTargetFPID().GetLibItemName().empty() )
356 {
358
359 // Save Library As
360 const wxString& src_libNickname = m_frame->GetTargetFPID().GetLibNickname();
361 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, src_libNickname, true );
362 wxCHECK( optUri, 0 );
363
364 if( m_frame->SaveLibraryAs( *optUri ) )
365 m_frame->SyncLibraryTree( true );
366 }
367 else if( m_frame->GetTargetFPID() == m_frame->GetLoadedFPID() )
368 {
369 // Save Footprint As
370 if( footprint() && m_frame->SaveFootprintAs( footprint() ) )
371 {
372 view()->Update( footprint() );
373 m_frame->ClearModify();
374
375 // Get rid of the save-will-update-board-only (or any other dismissable warning)
376 WX_INFOBAR* infobar = m_frame->GetInfoBar();
377
378 if( infobar->IsShownOnScreen() && infobar->HasCloseButton() )
379 infobar->Dismiss();
380
381 canvas()->ForceRefresh();
382 m_frame->SyncLibraryTree( true );
383 }
384 }
385 else
386 {
387 // Save Selected Footprint As
388 FOOTPRINT* footprint = m_frame->LoadFootprint( m_frame->GetTargetFPID() );
389
390 if( footprint && m_frame->SaveFootprintAs( footprint ) )
391 {
392 m_frame->SyncLibraryTree( true );
393 m_frame->FocusOnLibID( footprint->GetFPID() );
394 }
395 }
396
397 m_frame->RefreshLibraryTree();
398 return 0;
399}
400
401
403{
404 getEditFrame<FOOTPRINT_EDIT_FRAME>()->RevertFootprint();
405 return 0;
406}
407
408
410{
411 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
412
413 if( fpID == m_frame->GetLoadedFPID() )
414 {
415 m_copiedFootprint = std::make_unique<FOOTPRINT>( *m_frame->GetBoard()->GetFirstFootprint() );
416 m_copiedFootprint->SetParent( nullptr );
417 }
418 else
419 {
420 m_copiedFootprint.reset( m_frame->LoadFootprint( fpID ) );
421 }
422
423 if( aEvent.IsAction( &PCB_ACTIONS::cutFootprint ) )
424 DeleteFootprint( aEvent );
425
426 return 0;
427}
428
429
431{
432 if( m_copiedFootprint && !m_frame->GetLibTree()->GetSelectedLibId().GetLibNickname().empty() )
433 {
434 wxString newLib = m_frame->GetLibTree()->GetSelectedLibId().GetLibNickname();
435 wxString newName = m_copiedFootprint->GetFPID().GetLibItemName();
436
437 while( PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->FootprintExists( newLib, newName ) )
438 newName += _( "_copy" );
439
440 m_copiedFootprint->SetFPID( LIB_ID( newLib, newName ) );
441 m_frame->SaveFootprintInLibrary( m_copiedFootprint.get(), newLib );
442
443 m_frame->SyncLibraryTree( true );
444 m_frame->LoadFootprintFromLibrary( m_copiedFootprint->GetFPID() );
445 m_frame->FocusOnLibID( m_copiedFootprint->GetFPID() );
446 m_frame->RefreshLibraryTree();
447 }
448
449 return 0;
450}
451
452
454{
455 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
457
458 if( fpID == m_frame->GetLoadedFPID() )
459 footprint = new FOOTPRINT( *m_frame->GetBoard()->GetFirstFootprint() );
460 else
461 footprint = m_frame->LoadFootprint( m_frame->GetTargetFPID() );
462
463 if( footprint && m_frame->DuplicateFootprint( footprint ) )
464 {
465 m_frame->SyncLibraryTree( true );
466 m_frame->LoadFootprintFromLibrary( footprint->GetFPID() );
467 m_frame->FocusOnLibID( footprint->GetFPID() );
468 m_frame->RefreshLibraryTree();
469 }
470
471 return 0;
472}
473
474
476{
479
480 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
481 wxString libraryName = fpID.GetLibNickname();
482 wxString oldName = fpID.GetLibItemName();
483 wxString newName;
484 wxString msg;
485
486 if( !libTool->RenameLibrary( _( "Change Footprint Name" ), oldName,
487 [&]( const wxString& aNewName )
488 {
489 newName = aNewName;
490
491 if( newName.IsEmpty() )
492 {
493 wxMessageBox( _( "Footprint must have a name." ) );
494 return false;
495 }
496
497 // If no change, accept it without prompting
498 if( oldName != newName && adapter->FootprintExists( libraryName, newName ) )
499 {
500 msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
501 newName, libraryName );
502
503 KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
504 wxOK | wxCANCEL | wxICON_WARNING );
505 errorDlg.SetOKLabel( _( "Overwrite" ) );
506
507 return errorDlg.ShowModal() == wxID_OK;
508 }
509
510 return true;
511 } ) )
512 {
513 return 0; // canceled by user
514 }
515
516 if( newName == oldName )
517 return 0;
518
519 FOOTPRINT* footprint = nullptr;
520
521 if( fpID == m_frame->GetLoadedFPID() )
522 {
523 footprint = m_frame->GetBoard()->GetFirstFootprint();
524
525 if( footprint )
526 {
527 footprint->SetFPID( LIB_ID( libraryName, newName ) );
528
529 if( footprint->GetValue() == oldName )
530 footprint->SetValue( newName );
531
532 m_frame->OnModify();
533 m_frame->UpdateView();
534 }
535 }
536 else
537 {
538 footprint = m_frame->LoadFootprint( fpID );
539
540 if( footprint )
541 {
542 try
543 {
544 footprint->SetFPID( LIB_ID( libraryName, newName ) );
545
546 if( footprint->GetValue() == oldName )
547 footprint->SetValue( newName );
548
549 // Both names are one file on a case-insensitive filesystem.
550 adapter->DeleteFootprint( libraryName, oldName );
551
552 m_frame->SaveFootprintInLibrary( footprint, libraryName );
553 }
554 catch( const IO_ERROR& ioe )
555 {
556 DisplayErrorMessage( m_frame, _( "Error renaming footprint" ), ioe.What() );
557 }
558 catch( ... )
559 {
560 // Best efforts...
561 }
562 }
563 }
564
565 if( footprint )
566 m_frame->RenameFootprintTab( fpID, LIB_ID( libraryName, newName ) );
567
568 wxDataViewItem treeItem = m_frame->GetLibTreeAdapter()->FindItem( fpID );
569
570 if( footprint )
571 {
572 m_frame->UpdateLibraryTree( treeItem, footprint );
573 m_frame->FocusOnLibID( LIB_ID( libraryName, newName ) );
574 }
575
576 return 0;
577}
578
579
581{
583 const LIB_ID fpID = frame->GetTargetFPID();
584
585 if( frame->DeleteFootprintFromLibrary( fpID, true ) )
586 {
587 // Close only the deleted footprint's tab, leaving the others open.
588 frame->CloseFootprintTab( fpID );
589
590 frame->SyncLibraryTree( true );
591 }
592
593 return 0;
594}
595
596
598{
599 bool is_last_fp_from_brd = m_frame->IsCurrentFPFromBoard();
600
602
603 // A cancelled file dialog must leave the editor exactly as it was
604 if( !m_frame->ImportFootprint() )
605 return 0;
606
607 if( m_frame->GetBoard()->GetFirstFootprint() )
608 m_frame->GetBoard()->GetFirstFootprint()->ClearFlags();
609
610 frame()->ClearUndoRedoList();
611
612 // Update the save items if needed.
613 if( is_last_fp_from_brd )
614 {
615 m_frame->ReCreateMenuBar();
616 m_frame->ReCreateHToolbar();
617 }
618
619 m_toolMgr->RunAction( ACTIONS::zoomFitScreen );
620 m_frame->OnModify();
621 return 0;
622}
623
624
626{
627 if( FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint() )
628 m_frame->ExportFootprint( fp );
629
630 return 0;
631}
632
633
635{
636 FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
637
638 if( !fp )
639 {
640 wxMessageBox( _( "No footprint to export" ) );
641 return 0;
642 }
643
644 wxFileName fn( fp->GetFPID().GetLibItemName() );
645 fn.SetExt( FILEEXT::SVGFileExtension );
646
647 wxString pro_dir = wxPathOnly( m_frame->Prj().GetProjectFullName() );
648
649 wxString fullFileName = wxFileSelector( _( "SVG File Name" ), pro_dir, fn.GetFullName(), FILEEXT::SVGFileExtension,
650 FILEEXT::SVGFileWildcard(), wxFD_SAVE, m_frame );
651
652 if( !fullFileName.IsEmpty() )
653 {
654 PCB_PLOT_PARAMS plotOpts;
655 plotOpts.SetFormat( PLOT_FORMAT::SVG );
656 plotOpts.SetColorSettings( m_frame->GetColorSettings() );
657 plotOpts.SetScale( 1.0 );
658 plotOpts.SetAutoScale( false );
659
661
662 PlotFootprintToSVG( *fp, m_frame->Prj(), nullptr, plotOpts, layersToPlot, LSEQ(), fullFileName );
663 }
664
665 return 0;
666}
667
668
670{
671 wxCHECK( m_frame, 0 );
672
673 const wxString libNickname = m_frame->GetTargetFPID().GetUniStringLibNickname();
674
675 if( libNickname.IsEmpty() )
676 {
677 m_frame->ShowInfoBarError( _( "Select a library to compare against another." ) );
678 return 0;
679 }
680
682
683 wxCHECK( adapter, 0 );
684
685 std::optional<LIBRARY_TABLE_ROW*> row = adapter->GetRow( libNickname );
686
687 if( !row )
688 {
689 m_frame->ShowInfoBarError( wxString::Format( _( "Library '%s' is not in the footprint "
690 "library table." ),
691 libNickname ) );
692 return 0;
693 }
694
695 // MakeAbsolute so relative table URIs resolve from the project dir, not
696 // the process cwd.
697 wxFileName currentFn = wxFileName::DirName(
698 LIBRARY_MANAGER::GetFullURI( *row, /*aSubstituted=*/true ) );
699 currentFn.MakeAbsolute();
700 const wxString currentPath = currentFn.GetPath();
701
702 wxDirDialog dlg( m_frame, _( "Choose .pretty Folder to Compare With" ), wxEmptyString,
703 wxDD_DIR_MUST_EXIST );
704
705 if( dlg.ShowModal() != wxID_OK )
706 return 0;
707
708 wxFileName otherFn = wxFileName::DirName( dlg.GetPath() );
709 otherFn.MakeAbsolute();
710
711 if( otherFn.GetDirs().IsEmpty()
712 || !otherFn.GetDirs().Last().EndsWith( wxS( ".pretty" ) ) )
713 {
714 m_frame->ShowInfoBarError(
715 _( "Select a KiCad footprint library folder (ends with .pretty)." ) );
716 return 0;
717 }
718
719 if( otherFn.SameAs( currentFn ) )
720 {
721 m_frame->ShowInfoBarError(
722 _( "Select a different .pretty folder than the active library." ) );
723 return 0;
724 }
725
726 const wxString otherPath = otherFn.GetPath();
727
728 std::vector<std::unique_ptr<FOOTPRINT>> beforeStorage;
729 std::vector<std::unique_ptr<FOOTPRINT>> afterStorage;
732
733 auto load =
734 [&]( const wxString& aPath,
735 std::vector<std::unique_ptr<FOOTPRINT>>& aOwners,
737 {
738 try
739 {
740 auto loaded = KICAD_DIFF::FP_LIB_DIFFER::LoadLibrary( aPath );
741 aOwners = std::move( loaded.first );
742 aMap = std::move( loaded.second );
743 return true;
744 }
745 catch( const IO_ERROR& ioe )
746 {
747 m_frame->ShowInfoBarError(
748 wxString::Format( _( "Failed to load %s: %s" ), aPath, ioe.What() ) );
749 }
750 catch( const std::exception& e )
751 {
752 m_frame->ShowInfoBarError(
753 wxString::Format( _( "Failed to load %s: %s" ), aPath,
754 wxString::FromUTF8( e.what() ) ) );
755 }
756
757 return false;
758 };
759
760 if( !load( currentPath, beforeStorage, beforeMap ) )
761 return 0;
762
763 if( !load( otherPath, afterStorage, afterMap ) )
764 return 0;
765
766 KICAD_DIFF::FP_LIB_DIFFER differ( beforeMap, afterMap, otherPath );
768
769 DIALOG_KICAD_DIFF dlgDiff( m_frame, currentPath, otherPath, result );
770 dlgDiff.ShowModal();
771
772 return 0;
773}
774
775
777{
778 // No check for multi selection since the context menu option must be hidden in that case
779 LIB_ID libId = m_frame->GetTargetFPID();
780
781 wxString libName = libId.GetLibNickname();
782 wxString libItemName = libId.GetLibItemName();
783 wxString path = wxEmptyString;
784
786 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
787
788 if( !optUri )
789 return 0;
790
791 path = *optUri;
792
793 wxString fileExt = wxEmptyString;
794
795 // If selection is footprint
796 if( !libItemName.IsEmpty() )
798
799 wxFileName fileName( path, libItemName, fileExt );
800 wxString explorerCommand;
801
802 if( COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
803 explorerCommand = cfg->m_System.file_explorer;
804
805 if( explorerCommand.IsEmpty() )
806 {
807 path = fileName.GetFullPath().BeforeLast( wxFileName::GetPathSeparator() );
808
809 if( !path.IsEmpty() && wxDirExists( path ) )
811
812 return 0;
813 }
814
815 if( !explorerCommand.EndsWith( "%F" ) )
816 {
817 wxMessageBox( _( "Missing/malformed file explorer argument '%F' in common settings." ) );
818 return 0;
819 }
820
821 wxString escapedFilePath = fileName.GetFullPath();
822 escapedFilePath.Replace( wxS( "\"" ), wxS( "_" ) );
823
824 wxString fileArg = wxEmptyString;
825 fileArg << '"' << escapedFilePath << '"';
826
827 explorerCommand.Replace( wxT( "%F" ), fileArg );
828
829 if( !explorerCommand.IsEmpty() )
830 wxExecute( explorerCommand );
831
832 return 0;
833}
834
835
837{
838 wxString fullEditorName = Pgm().GetTextEditor();
839
840 if( fullEditorName.IsEmpty() )
841 {
842 wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
843 return 0;
844 }
845
846 // No check for multi selection since the context menu option must be hidden in that case
847 LIB_ID libId = m_frame->GetLibTree()->GetSelectedLibId();
848
850
851 wxString libName = libId.GetLibNickname();
852 wxString libItemName = wxEmptyString;
853
854 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
855
856 if( !optUri )
857 return 0;
858
859 libItemName = *optUri;
860 libItemName << wxFileName::GetPathSeparator();
861 libItemName << libId.GetLibItemName();
862 libItemName << '.' + FILEEXT::KiCadFootprintFileExtension;
863
864 if( !wxFileName::FileExists( libItemName ) )
865 return 0;
866
867 ExecuteFile( fullEditorName, libItemName.wc_str(), nullptr, false );
868
869 return 0;
870}
871
872
874{
875 if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
876 {
877 std::optional<wxString> url = GetFootprintDocumentationURL( *footprint );
878
879 if( !url.has_value() )
880 {
881 frame()->ShowInfoBarMsg( _( "No datasheet found in the footprint." ) );
882 }
883 else
884 {
885 // Only absolute URLs are supported
886 SEARCH_STACK* searchStack = nullptr;
887 GetAssociatedDocument( m_frame, *url, &m_frame->Prj(), searchStack,
888 { m_frame->GetBoard(), footprint } );
889 }
890 }
891 return 0;
892}
893
894
896{
897 m_frame->LoadFootprintFromLibrary( m_frame->GetLibTree()->GetSelectedLibId() );
898 return 0;
899}
900
901
903{
904 FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint();
905
906 if( !footprint || !m_frame->IsCurrentFPFromBoard() )
907 {
908 wxBell();
909 return 0;
910 }
911
912 m_frame->LoadFootprintFromLibrary( footprint->GetFPID() );
913
914 if( !m_frame->IsLibraryTreeShown() )
915 m_frame->ToggleLibraryTree();
916
917 return 0;
918}
919
920
922{
923 m_frame->ToggleLayersManager();
924 return 0;
925}
926
927
929{
930 m_frame->ToggleProperties();
931 return 0;
932}
933
934
936{
937 // Check if called from tree context menu
939 {
940 LIB_ID treeLibId = m_frame->GetLibTree()->GetSelectedLibId();
941
942 // Check if a different footprint is selected in the tree
943 if( treeLibId.IsValid()
944 && ( !m_frame->GetBoard()->GetFirstFootprint()
945 || m_frame->GetBoard()->GetFirstFootprint()->GetFPID() != treeLibId ) )
946 {
947 // Edit properties directly from library without loading to canvas
949 return 0;
950 }
951 }
952
953 if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
954 {
955 getEditFrame<FOOTPRINT_EDIT_FRAME>()->OnEditItemRequest( footprint );
956 m_frame->GetCanvas()->Refresh();
957 }
958
959 return 0;
960}
961
962
964{
965 // Load the footprint from the library (without adding it to the canvas)
966 FOOTPRINT* libraryFootprint = m_frame->LoadFootprint( aLibId );
967
968 if( !libraryFootprint )
969 return;
970
971 // Create a temporary board to hold the footprint (required by the dialog)
972 std::unique_ptr<BOARD> tempBoard( new BOARD() );
973
974 // Set up the temp board with the current project and board settings.
975 // Use reference-only mode to avoid modifying the project's settings.
976 tempBoard->SetDesignSettings( m_frame->GetBoard()->GetDesignSettings() );
977 tempBoard->SetProject( &m_frame->Prj(), true );
978 tempBoard->SetBoardUse( BOARD_USE::FPHOLDER );
979 tempBoard->SynchronizeProperties();
980
981 // Create a copy to work with and add it to the temporary board
982 FOOTPRINT* tempFootprint = static_cast<FOOTPRINT*>( libraryFootprint->Clone() );
983 delete libraryFootprint;
984
985 tempBoard->Add( tempFootprint );
986 tempFootprint->SetParent( tempBoard.get() );
987
988 LIB_ID oldFPID = tempFootprint->GetFPID();
989
990 // Open the properties dialog
991 DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( m_frame, tempFootprint );
992
993 if( dialog.ShowQuasiModal() != wxID_OK )
994 return;
995
996 // Remove from temporary board before saving (to avoid double-delete)
997 tempBoard->Remove( tempFootprint );
998
999 // Save the modified footprint back to the library
1001 wxString libName = aLibId.GetLibNickname();
1002
1003 try
1004 {
1005 adapter->SaveFootprint( libName, tempFootprint, true );
1006
1007 // Update the tree view
1008 wxDataViewItem treeItem = m_frame->GetLibTreeAdapter()->FindItem( oldFPID );
1009 m_frame->UpdateLibraryTree( treeItem, tempFootprint );
1010 m_frame->SyncLibraryTree( true );
1011
1012 // Clean up
1013 delete tempFootprint;
1014 }
1015 catch( const IO_ERROR& ioe )
1016 {
1017 delete tempFootprint;
1018 DisplayError( m_frame, ioe.What() );
1019 }
1020}
1021
1022
1024{
1025 getEditFrame<FOOTPRINT_EDIT_FRAME>()->ShowPadPropertiesDialog( nullptr );
1026 return 0;
1027}
1028
1029
1031{
1033 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, true );
1034
1035 dlg.ShowModal();
1036 return 0;
1037}
1038
1039
1041{
1042 if( !m_checkerDialog )
1043 {
1045 m_checkerDialog->Show( true );
1046 }
1047 else // The dialog is just not visible (because the user has double clicked on an error item)
1048 {
1049 m_checkerDialog->Show( true );
1050 }
1051
1052 return 0;
1053}
1054
1055
1057{
1058 if( !m_checkerDialog )
1060
1061 if( !m_checkerDialog->IsShownOnScreen() )
1062 m_checkerDialog->Show( true );
1063
1064 m_checkerDialog->SelectMarker( aMarker );
1065}
1066
1067
1069{
1070 if( m_checkerDialog )
1071 {
1072 m_checkerDialog->Destroy();
1073 m_checkerDialog = nullptr;
1074 }
1075}
1076
1077
1079{
1080 FOOTPRINT* footprint = board()->Footprints().front();
1081 int errors = 0;
1082 wxString details;
1083
1084 // Repair duplicate IDs and missing nets.
1085 std::set<KIID> ids;
1086 int duplicates = 0;
1087
1088 auto processItem =
1089 [&]( EDA_ITEM* aItem )
1090 {
1091 if( ids.count( aItem->m_Uuid ) )
1092 {
1093 duplicates++;
1094 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
1095 boardItem->ResetUuid();
1096 }
1097
1098 ids.insert( aItem->m_Uuid );
1099 };
1100
1101 // Footprint IDs are the most important, so give them the first crack at "claiming" a
1102 // particular KIID.
1103
1104 processItem( footprint );
1105
1106 // After that the principal use is for DRC marker pointers, which are most likely to pads.
1107
1108 for( PAD* pad : footprint->Pads() )
1109 processItem( pad );
1110
1111 // From here out I don't think order matters much.
1112
1113 processItem( &footprint->Reference() );
1114 processItem( &footprint->Value() );
1115
1116 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1117 processItem( item );
1118
1119 for( ZONE* zone : footprint->Zones() )
1120 processItem( zone );
1121
1122 for( PCB_GROUP* group : footprint->Groups() )
1123 processItem( group );
1124
1125 if( duplicates )
1126 {
1127 errors += duplicates;
1128 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
1129 }
1130
1131 if( errors )
1132 {
1133 m_frame->OnModify();
1134
1135 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
1136 DisplayInfoMessage( m_frame, msg, details );
1137 }
1138 else
1139 {
1140 DisplayInfoMessage( m_frame, _( "No footprint problems found." ) );
1141 }
1142
1143 return 0;
1144}
1145
1146
1147// The appearance panel also claims Ctrl+Tab for layer-preset cycling, so it wins when focused.
1149{
1150 wxWindow* appearance = aFrame->GetAppearancePanel();
1151
1152 if( !appearance )
1153 return false;
1154
1155 for( wxWindow* focus = wxWindow::FindFocus(); focus; focus = focus->GetParent() )
1156 {
1157 if( focus == appearance )
1158 return true;
1159 }
1160
1161 return false;
1162}
1163
1164
1166{
1168 return 0;
1169
1170 m_frame->AdvanceFootprintTab( true );
1171 return 0;
1172}
1173
1174
1176{
1178 return 0;
1179
1180 m_frame->AdvanceFootprintTab( false );
1181 return 0;
1182}
1183
1184
1186{
1187 m_frame->CloseActiveFootprintTab();
1188 return 0;
1189}
1190
1191
1193{
1194 if( m_frame->GetTargetFPID().GetLibNickname().empty() )
1195 return 0;
1196
1197 if( m_frame->HasModifiedFootprintTabs() )
1198 {
1199 DisplayInfoMessage( m_frame, _( "Save or discard the changes in all modified footprint tabs before opening "
1200 "the Footprint Fields Table." ) );
1201 return 0;
1202 }
1203
1205
1206 dlg.ShowModal();
1207 return 0;
1208}
1209
1210
1212{
1213 // clang-format off
1216 PCB_ACTIONS::createFootprint.MakeEvent() );
1223
1229
1237
1241
1244
1247
1251
1256 // clang-format on
1257
1258 // Line modes for the footprint editor: explicit modes, next-mode, and toolbar sync
1264}
1265
1267{
1268 LEADER_MODE mode = aEvent.Parameter<LEADER_MODE>();
1269 GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode = mode;
1270 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1272 return 0;
1273}
1274
1276{
1278
1279 if( !f )
1280 return 0;
1281
1282 LEADER_MODE mode = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode;
1283
1284 switch( mode )
1285 {
1288 default:
1290 }
1291
1292 return 0;
1293}
@ FPHOLDER
Definition board.h:402
static TOOL_ACTION openWithTextEditor
Definition actions.h:64
static TOOL_ACTION revert
Definition actions.h:58
static TOOL_ACTION saveAs
Definition actions.h:55
static TOOL_ACTION openDirectory
Definition actions.h:65
static TOOL_ACTION showDatasheet
Definition actions.h:263
static TOOL_ACTION save
Definition actions.h:54
static TOOL_ACTION zoomFitScreen
Definition actions.h:138
static TOOL_ACTION showProperties
Definition actions.h:262
static TOOL_ACTION refreshPreview
Definition actions.h:155
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
void BuildListOfNets()
Definition board.h:1178
const FOOTPRINTS & Footprints() const
Definition board.h:464
File-compare dialog (Phase 7).
int ShowModal() override
void SelectToolbarAction(const TOOL_ACTION &aAction) override
Select the given action in the toolbar group which contains it, if any.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Return a pointer to the KIGFX::VIEW_CONTROLS instance used in the panel.
void ForceRefresh()
Force a redraw.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:160
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
int Revert(const TOOL_EVENT &aEvent)
int OpenWithTextEditor(const TOOL_EVENT &aEvent)
int PasteFootprint(const TOOL_EVENT &aEvent)
DIALOG_FOOTPRINT_CHECKER * m_checkerDialog
int CutCopyFootprint(const TOOL_EVENT &aEvent)
int EditFootprint(const TOOL_EVENT &aEvent)
int CloseTab(const TOOL_EVENT &aEvent)
int ToggleProperties(const TOOL_EVENT &aEvent)
int Save(const TOOL_EVENT &aEvent)
int OpenDirectory(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int NextTab(const TOOL_EVENT &aEvent)
int ExportFootprintAsSVG(const TOOL_EVENT &aEvent)
int ShowLibraryFieldsTable(const TOOL_EVENT &aEvent)
int NewFootprint(const TOOL_EVENT &aEvent)
int CompareLibraryWithFile(const TOOL_EVENT &aEvent)
Diff the currently-selected footprint library against another .pretty directory.
int DefaultPadProperties(const TOOL_EVENT &aEvent)
Edit the properties used for new pad creation.
void CrossProbe(const PCB_MARKER *aMarker)
int ChangeLineMode(const TOOL_EVENT &aEvent)
int ImportFootprint(const TOOL_EVENT &aEvent)
int CleanupGraphics(const TOOL_EVENT &aEvent)
int ShowDatasheet(const TOOL_EVENT &aEvent)
void tryToSaveFootprintInLibrary(FOOTPRINT &aFootprint, const LIB_ID &aLibId)
Try to save the footprint in the library, if it is valid and writable.
int PrevTab(const TOOL_EVENT &aEvent)
int Properties(const TOOL_EVENT &aEvent)
int ToggleLayersManager(const TOOL_EVENT &aEvent)
int RepairFootprint(const TOOL_EVENT &aEvent)
int RenameFootprint(const TOOL_EVENT &aEvent)
int DuplicateFootprint(const TOOL_EVENT &aEvent)
std::unique_ptr< FOOTPRINT > m_copiedFootprint
bool Init() override
Init() is called once upon a registration of the tool.
int CreateFootprintFromWizard(const TOOL_EVENT &aEvent)
int OnAngleSnapModeChanged(const TOOL_EVENT &aEvent)
int ExportFootprint(const TOOL_EVENT &aEvent)
int EditLibraryFootprint(const TOOL_EVENT &aEvent)
void editFootprintPropertiesFromLibrary(const LIB_ID &aLibId)
int DeleteFootprint(const TOOL_EVENT &aEvent)
int SaveAs(const TOOL_EVENT &aEvent)
void setTransitions() override
< Set up handlers for various events.
int CheckFootprint(const TOOL_EVENT &aEvent)
An interface to the global shared library manager that is schematic-specific and linked to one projec...
SAVE_T SaveFootprint(const wxString &aNickname, const FOOTPRINT *aFootprint, bool aOverwrite=true)
Write aFootprint to an existing library given by aNickname.
FOOTPRINT * GetBuiltFootprint()
Return a duplicate of the generated footprint. The caller takes ownership.
void SetPosition(const VECTOR2I &aPos) override
void SetFPID(const LIB_ID &aFPID)
Definition footprint.h:475
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
const LIB_ID & GetFPID() const
Definition footprint.h:474
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()
Diff two .pretty footprint library directories.
static std::pair< std::vector< std::unique_ptr< FOOTPRINT > >, FOOTPRINT_MAP > LoadLibrary(const wxString &aPrettyPath)
Load a .pretty directory into a FOOTPRINT_MAP.
DOCUMENT_DIFF Diff() override
Produce a DOCUMENT_DIFF of the inputs the concrete differ was constructed with.
std::map< wxString, const FOOTPRINT * > FOOTPRINT_MAP
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:38
int ShowModal() override
Definition kidialog.cpp:89
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition pcb_view.cpp:87
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool ShowModal(wxString *aResult=nullptr, wxWindow *aResultantFocusWindow=nullptr)
Show this wxFrame as if it were a modal dialog, with all other instantiated wxFrames disabled until t...
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
Module editor specific tools.
bool RenameLibrary(const wxString &aTitle, const wxString &aName, std::function< bool(const wxString &aNewName)> aValidator)
void AddContextMenuItems(CONDITIONAL_MENU *aMenu)
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
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
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
const wxString GetUniStringLibNickname() const
Definition lib_id.h:84
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
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition lseq.h:47
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition lset.cpp:400
static const LSET & AllLayersMask()
Definition lset.cpp:637
Definition pad.h:61
static TOOL_ACTION lineModeFree
Unconstrained angle mode (icon lines_any)
static TOOL_ACTION deleteFootprint
static TOOL_ACTION renameFootprint
static TOOL_ACTION showLayersManager
static TOOL_ACTION createFootprint
static TOOL_ACTION editFootprint
static TOOL_ACTION exportFootprint
static TOOL_ACTION editTextAndGraphics
static TOOL_ACTION lineMode45
45-degree-or-orthogonal mode (icon hv45mode)
static TOOL_ACTION angleSnapModeChanged
Notification event when angle mode changes.
static TOOL_ACTION newFootprint
static TOOL_ACTION defaultPadProperties
static TOOL_ACTION prevFootprintTab
static TOOL_ACTION importFootprint
static TOOL_ACTION pasteFootprint
static TOOL_ACTION footprintProperties
static TOOL_ACTION lineMode90
90-degree-only mode (icon lines90)
static TOOL_ACTION closeFootprintTab
static TOOL_ACTION nextFootprintTab
static TOOL_ACTION showLibFootprintFieldsTable
static TOOL_ACTION checkFootprint
static TOOL_ACTION editLibFpInFpEditor
static TOOL_ACTION duplicateFootprint
static TOOL_ACTION cutFootprint
static TOOL_ACTION repairFootprint
static TOOL_ACTION exportFootprintAsSVG
static TOOL_ACTION compareFpLibraryWithFile
static TOOL_ACTION copyFootprint
static TOOL_ACTION cleanupGraphics
APPEARANCE_CONTROLS * GetAppearancePanel()
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:51
Parameters and options when plotting/printing a board.
void SetAutoScale(bool aFlag)
void SetScale(double aVal)
void SetColorSettings(COLOR_SETTINGS *aSettings)
void SetFormat(PLOT_FORMAT aFormat)
T * frame() const
KIGFX::PCB_VIEW * view() const
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
BOARD * board() const
PCB_DRAW_PANEL_GAL * canvas() const
FOOTPRINT * footprint() const
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition pgm_base.cpp:216
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:125
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
Look for files in a number of paths.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition tool_base.cpp:40
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
Generic, UI-independent tool event.
Definition tool_event.h:167
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:484
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
std::unique_ptr< TOOL_MENU > m_menu
The functions below are not yet implemented - their interface may change.
bool empty() const
Definition utf8.h:105
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
bool HasCloseButton() const
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Handle a list of polygons defining a copper zone.
Definition zone.h:70
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
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)
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
Definition eda_doc.cpp:59
This file is part of the common library.
static bool appearancePanelHasFocus(FOOTPRINT_EDIT_FRAME *aFrame)
@ FRAME_FOOTPRINT_WIZARD
Definition frame_type.h:42
std::optional< wxString > GetFootprintDocumentationURL(const FOOTPRINT &aFootprint)
Get a URL to the documentation for a LIB_ID in a LIBRARY_TABLE.
LEADER_MODE
The kind of the leader line.
@ DEG45
45 Degree only
@ DIRECT
Unconstrained point-to-point.
@ DEG90
90 Degree only
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition gestfich.cpp:166
static const std::string SVGFileExtension
static const std::string KiCadFootprintFileExtension
static wxString SVGFileWildcard()
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
Class to handle a set of BOARD_ITEMs.
bool PlotFootprintToSVG(const FOOTPRINT &aFootprint, PROJECT &aProject, const std::map< wxString, wxString > *aVarOverrides, PCB_PLOT_PARAMS &aPlotOpts, const LSEQ &aLayersToPlot, const LSEQ &aLayersOnAll, const wxString &aFileName, REPORTER *aReporter)
Plot a footprint to an SVG file, with the footprint origin at the SVG origin and the page/viewBox siz...
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
T * GetAppSettings(const char *aFilename)
The full set of changes between two parsed documents of one type.
std::string path
wxString result
Test unit parsing edge cases and error handling.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707
Definition of file extensions used in Kicad.