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>
59#include <kiway.h>
60#include <pcb_plotter.h>
61#include <project_pcb.h>
62#include <view/view_controls.h>
67#include <wx/dirdlg.h>
68
69
71 PCB_TOOL_BASE( "pcbnew.ModuleEditor" ),
72 m_frame( nullptr ),
73 m_checkerDialog( nullptr )
74{
75}
76
77
85
86
88{
89 LIBRARY_EDITOR_CONTROL* libraryTreeTool = m_toolMgr->GetTool<LIBRARY_EDITOR_CONTROL>();
90
91 // Build a context menu for the footprint tree
92 //
93 CONDITIONAL_MENU& ctxMenu = m_menu->GetMenu();
94
95 auto libSelectedCondition =
96 [this]( const SELECTION& aSel )
97 {
98 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
99 return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
100 };
101
102 // The libInferredCondition allows you to do things like New Symbol and Paste with a
103 // symbol selected (in other words, when we know the library context even if the library
104 // itself isn't selected.
105 auto libInferredCondition =
106 [this]( const SELECTION& aSel )
107 {
108 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
109 return !sel.GetLibNickname().empty();
110 };
111
112 auto fpSelectedCondition =
113 [this]( const SELECTION& aSel )
114 {
115 LIB_ID sel = m_frame->GetLibTree()->GetSelectedLibId();
116 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
117 };
118
119 auto fpExportCondition =
120 [this]( const SELECTION& aSel )
121 {
122 FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
123 return fp != nullptr;
124 };
125
126 auto canOpenExternally =
127 [this]( const SELECTION& aSel )
128 {
129 // The option is shown if the editor has no current edits,
130 // dumb/simple guard against opening a new file that does not exist on disk
131 bool ret = !m_frame->IsContentModified();
132 return ret;
133 };
134
135// clang-format off
136 ctxMenu.AddItem( PCB_ACTIONS::newFootprint, libSelectedCondition, 10 );
137 ctxMenu.AddItem( PCB_ACTIONS::createFootprint, libSelectedCondition, 10 );
138
139 ctxMenu.AddSeparator( 10 );
140 ctxMenu.AddItem( ACTIONS::save, SELECTION_CONDITIONS::ShowAlways, 10 );
141 ctxMenu.AddItem( ACTIONS::saveAs, libSelectedCondition || fpSelectedCondition, 10 );
142 ctxMenu.AddItem( ACTIONS::revert, libSelectedCondition || libInferredCondition, 10 );
143
144 ctxMenu.AddSeparator( 10 );
145 ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition, 10 );
146 ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition, 10 );
147 ctxMenu.AddItem( PCB_ACTIONS::pasteFootprint, libInferredCondition, 10 );
148 ctxMenu.AddItem( PCB_ACTIONS::duplicateFootprint, fpSelectedCondition, 10 );
149 ctxMenu.AddItem( PCB_ACTIONS::renameFootprint, fpSelectedCondition, 10 );
150 ctxMenu.AddItem( PCB_ACTIONS::deleteFootprint, fpSelectedCondition, 10 );
151 ctxMenu.AddItem( PCB_ACTIONS::footprintProperties, fpSelectedCondition, 10 );
152
153 ctxMenu.AddSeparator( 100 );
154 ctxMenu.AddItem( PCB_ACTIONS::importFootprint, libInferredCondition, 100 );
155 ctxMenu.AddItem( PCB_ACTIONS::exportFootprint, fpExportCondition, 100 );
156
157 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText )
158 {
159 ctxMenu.AddSeparator( 200 );
160 ctxMenu.AddItem( ACTIONS::openWithTextEditor, canOpenExternally && fpSelectedCondition, 200 );
161 }
162
163 if( ADVANCED_CFG::GetCfg().m_EnableLibDir )
164 {
165 ctxMenu.AddSeparator( 200 );
166 ctxMenu.AddItem( ACTIONS::openDirectory, canOpenExternally && ( libSelectedCondition || fpSelectedCondition ), 200 );
167 }
168
169 ctxMenu.AddSeparator( 300 );
170 ctxMenu.AddItem( PCB_ACTIONS::showLibFootprintFieldsTable, libInferredCondition, 300 );
171// clang-format on
172
173 libraryTreeTool->AddContextMenuItems( &ctxMenu );
174
175 // Ensure the left toolbar's Line modes group reflects the current setting at startup
176 if( m_toolMgr )
178
179 return true;
180}
181
182
184 const LIB_ID& aTargetLib )
185{
186 const wxString libraryName = aTargetLib.GetUniStringLibNickname();
187
188 if( aTargetLib.GetLibNickname().empty() )
189 {
190 // Do nothing - the footprint will need to be saved manually to assign
191 // to a library.
192 }
193 else
194 {
195 if( !PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->IsFootprintLibWritable( libraryName ) )
196 {
197 // If the library is not writeable, we'll give the user a
198 // footprint not in a library. But add a warning to let them know
199 // they didn't quite get what they wanted.
200 m_frame->ShowInfoBarWarning(
201 wxString::Format(
202 _( "The footprint could not be added to the selected library ('%s'). "
203 "This library is read-only." ),
204 libraryName ),
205 false );
206 // And the footprint will need to be saved manually
207 }
208 else
209 {
210 // Go ahead and save it to the library
211 LIB_ID fpid = aFootprint.GetFPID();
212 fpid.SetLibNickname( aTargetLib.GetLibNickname() );
213 aFootprint.SetFPID( fpid );
214
215 // Clear the modified flag only on a successful save, else the edits are silently
216 // lost (issue #23850).
217 if( m_frame->SaveFootprint( &aFootprint ) )
218 m_frame->ClearModify();
219 }
220 }
221}
222
223
225{
226 const LIB_ID selected = m_frame->GetTargetFPID();
227 const wxString libraryName = selected.GetUniStringLibNickname();
228
229 if( !m_frame->BeginNewFootprint( libraryName ) )
230 return 0;
231
232 FOOTPRINT* newFootprint = m_frame->CreateNewFootprint( wxEmptyString, libraryName );
233
234 if( !newFootprint )
235 return 0;
236
237 // Give the new footprint a resolvable identity so it opens in its own tab instead of
238 // overwriting the active one.
239 if( !libraryName.IsEmpty() )
240 {
241 newFootprint->SetFPID( LIB_ID( libraryName, newFootprint->GetFPID().GetLibItemName() ) );
242 }
243 else
244 {
245 newFootprint->SetParent( nullptr );
246 m_frame->CreateUnsavedFootprintTab();
247 }
248
250 m_frame->AddFootprintToBoard( newFootprint );
251
252 // Initialize data relative to nets and netclasses (for a new footprint the defaults are
253 // used). This is mandatory to handle and draw pads.
255 newFootprint->SetPosition( VECTOR2I( 0, 0 ) );
256 newFootprint->ClearFlags();
257
258 m_frame->Zoom_Automatique( false );
259 m_frame->GetScreen()->SetContentModified();
260 m_frame->OnModify();
261
262 tryToSaveFootprintInLibrary( *newFootprint, selected );
263
264 m_frame->UpdateView();
265 m_frame->GetCanvas()->ForceRefresh();
266 m_frame->Update3DView( true, true );
267
268 m_frame->SyncLibraryTree( false );
269 return 0;
270}
271
272
274{
275 const LIB_ID selected = m_frame->GetTargetFPID();
276
277 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_WIZARD, true, m_frame ) )
278 {
279 FOOTPRINT_WIZARD_FRAME* wizard = static_cast<FOOTPRINT_WIZARD_FRAME*>( frame );
280
281 if( wizard->ShowModal( nullptr, m_frame ) )
282 {
283 // Creates the new footprint from python script wizard
284 FOOTPRINT* newFootprint = wizard->GetBuiltFootprint();
285
286 if( newFootprint ) // i.e. if create footprint command is OK
287 {
288 if( !m_frame->BeginNewFootprint( selected.GetLibNickname() ) )
289 {
290 delete newFootprint;
291 wizard->Destroy();
292 return 0;
293 }
294
295 newFootprint->SetParent( nullptr );
296 m_frame->CreateUnsavedFootprintTab();
297
299 // Add the new object to board
300 m_frame->AddFootprintToBoard( newFootprint );
301
302 // Initialize data relative to nets and netclasses (for a new footprint the
303 // defaults are used). This is mandatory to handle and draw pads.
305 newFootprint->SetPosition( VECTOR2I( 0, 0 ) );
306 newFootprint->ClearFlags();
307
308 m_frame->Zoom_Automatique( false );
309 m_frame->GetScreen()->SetContentModified();
310 m_frame->OnModify();
311
312 tryToSaveFootprintInLibrary( *newFootprint, selected );
313
314 m_frame->UpdateView();
315 canvas()->Refresh();
316 m_frame->Update3DView( true, true );
317
318 m_frame->SyncLibraryTree( false );
319 }
320 }
321
322 wizard->Destroy();
323 }
324
325 return 0;
326}
327
328
330{
331 if( !footprint() ) // no loaded footprint
332 return 0;
333
334 const LIB_ID loadedId = m_frame->GetLoadedFPID();
335
336 // An unsaved import has no library identity for the tree selection to match, and save-as is the only
337 // way to give it one, so never let an unrelated selection swallow its save
338 if( m_frame->GetTargetFPID() == loadedId || loadedId.GetLibNickname().empty() )
339 {
340 if( m_frame->SaveFootprint( footprint() ) )
341 {
342 view()->Update( footprint() );
343
344 canvas()->ForceRefresh();
345 m_frame->ClearModify();
346 }
347 }
348
349 m_frame->RefreshLibraryTree();
350 return 0;
351}
352
353
355{
356 if( m_frame->GetTargetFPID().GetLibItemName().empty() )
357 {
359
360 // Save Library As
361 const wxString& src_libNickname = m_frame->GetTargetFPID().GetLibNickname();
362 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, src_libNickname, true );
363 wxCHECK( optUri, 0 );
364
365 if( m_frame->SaveLibraryAs( *optUri ) )
366 m_frame->SyncLibraryTree( true );
367 }
368 else if( m_frame->GetTargetFPID() == m_frame->GetLoadedFPID() )
369 {
370 // Save Footprint As
371 if( footprint() && m_frame->SaveFootprintAs( footprint() ) )
372 {
373 view()->Update( footprint() );
374 m_frame->ClearModify();
375
376 // Get rid of the save-will-update-board-only (or any other dismissable warning)
377 WX_INFOBAR* infobar = m_frame->GetInfoBar();
378
379 if( infobar->IsShownOnScreen() && infobar->HasCloseButton() )
380 infobar->Dismiss();
381
382 canvas()->ForceRefresh();
383 m_frame->SyncLibraryTree( true );
384 }
385 }
386 else
387 {
388 // Save Selected Footprint As
389 FOOTPRINT* footprint = m_frame->LoadFootprint( m_frame->GetTargetFPID() );
390
391 if( footprint && m_frame->SaveFootprintAs( footprint ) )
392 {
393 m_frame->SyncLibraryTree( true );
394 m_frame->FocusOnLibID( footprint->GetFPID() );
395 }
396 }
397
398 m_frame->RefreshLibraryTree();
399 return 0;
400}
401
402
404{
405 getEditFrame<FOOTPRINT_EDIT_FRAME>()->RevertFootprint();
406 return 0;
407}
408
409
411{
412 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
413
414 if( fpID == m_frame->GetLoadedFPID() )
415 {
416 m_copiedFootprint = std::make_unique<FOOTPRINT>( *m_frame->GetBoard()->GetFirstFootprint() );
417 m_copiedFootprint->SetParent( nullptr );
418 }
419 else
420 {
421 m_copiedFootprint.reset( m_frame->LoadFootprint( fpID ) );
422 }
423
424 if( aEvent.IsAction( &PCB_ACTIONS::cutFootprint ) )
425 DeleteFootprint( aEvent );
426
427 return 0;
428}
429
430
432{
433 if( m_copiedFootprint && !m_frame->GetLibTree()->GetSelectedLibId().GetLibNickname().empty() )
434 {
435 wxString newLib = m_frame->GetLibTree()->GetSelectedLibId().GetLibNickname();
436 wxString newName = m_copiedFootprint->GetFPID().GetLibItemName();
437
438 while( PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->FootprintExists( newLib, newName ) )
439 newName += _( "_copy" );
440
441 m_copiedFootprint->SetFPID( LIB_ID( newLib, newName ) );
442 m_frame->SaveFootprintInLibrary( m_copiedFootprint.get(), newLib );
443
444 m_frame->SyncLibraryTree( true );
445 m_frame->LoadFootprintFromLibrary( m_copiedFootprint->GetFPID() );
446 m_frame->FocusOnLibID( m_copiedFootprint->GetFPID() );
447 m_frame->RefreshLibraryTree();
448 }
449
450 return 0;
451}
452
453
455{
456 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
458
459 if( fpID == m_frame->GetLoadedFPID() )
460 footprint = new FOOTPRINT( *m_frame->GetBoard()->GetFirstFootprint() );
461 else
462 footprint = m_frame->LoadFootprint( m_frame->GetTargetFPID() );
463
464 if( footprint && m_frame->DuplicateFootprint( footprint ) )
465 {
466 m_frame->SyncLibraryTree( true );
467 m_frame->LoadFootprintFromLibrary( footprint->GetFPID() );
468 m_frame->FocusOnLibID( footprint->GetFPID() );
469 m_frame->RefreshLibraryTree();
470 }
471
472 return 0;
473}
474
475
477{
480
481 LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
482 wxString libraryName = fpID.GetLibNickname();
483 wxString oldName = fpID.GetLibItemName();
484 wxString newName;
485 wxString msg;
486
487 if( !libTool->RenameLibrary( _( "Change Footprint Name" ), oldName,
488 [&]( const wxString& aNewName )
489 {
490 newName = aNewName;
491
492 if( newName.IsEmpty() )
493 {
494 wxMessageBox( _( "Footprint must have a name." ) );
495 return false;
496 }
497
498 // If no change, accept it without prompting
499 if( oldName != newName && adapter->FootprintExists( libraryName, newName ) )
500 {
501 msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
502 newName, libraryName );
503
504 KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
505 wxOK | wxCANCEL | wxICON_WARNING );
506 errorDlg.SetOKLabel( _( "Overwrite" ) );
507
508 return errorDlg.ShowModal() == wxID_OK;
509 }
510
511 return true;
512 } ) )
513 {
514 return 0; // canceled by user
515 }
516
517 if( newName == oldName )
518 return 0;
519
520 FOOTPRINT* footprint = nullptr;
521
522 if( fpID == m_frame->GetLoadedFPID() )
523 {
524 footprint = m_frame->GetBoard()->GetFirstFootprint();
525
526 if( footprint )
527 {
528 footprint->SetFPID( LIB_ID( libraryName, newName ) );
529
530 if( footprint->GetValue() == oldName )
531 footprint->SetValue( newName );
532
533 m_frame->OnModify();
534 m_frame->UpdateView();
535 }
536 }
537 else
538 {
539 footprint = m_frame->LoadFootprint( fpID );
540
541 if( footprint )
542 {
543 try
544 {
545 footprint->SetFPID( LIB_ID( libraryName, newName ) );
546
547 if( footprint->GetValue() == oldName )
548 footprint->SetValue( newName );
549
550 // Both names are one file on a case-insensitive filesystem.
551 adapter->DeleteFootprint( libraryName, oldName );
552
553 m_frame->SaveFootprintInLibrary( footprint, libraryName );
554 }
555 catch( const IO_ERROR& ioe )
556 {
557 DisplayErrorMessage( m_frame, _( "Error renaming footprint" ), ioe.What() );
558 }
559 catch( ... )
560 {
561 // Best efforts...
562 }
563 }
564 }
565
566 if( footprint )
567 m_frame->RenameFootprintTab( fpID, LIB_ID( libraryName, newName ) );
568
569 wxDataViewItem treeItem = m_frame->GetLibTreeAdapter()->FindItem( fpID );
570
571 if( footprint )
572 {
573 m_frame->UpdateLibraryTree( treeItem, footprint );
574 m_frame->FocusOnLibID( LIB_ID( libraryName, newName ) );
575 }
576
577 return 0;
578}
579
580
582{
584 const LIB_ID fpID = frame->GetTargetFPID();
585
586 if( frame->DeleteFootprintFromLibrary( fpID, true ) )
587 {
588 // Close only the deleted footprint's tab, leaving the others open.
589 frame->CloseFootprintTab( fpID );
590
591 frame->SyncLibraryTree( true );
592 }
593
594 return 0;
595}
596
597
599{
600 bool is_last_fp_from_brd = m_frame->IsCurrentFPFromBoard();
601
603
604 // A cancelled file dialog must leave the editor exactly as it was
605 if( !m_frame->ImportFootprint() )
606 return 0;
607
608 if( m_frame->GetBoard()->GetFirstFootprint() )
609 m_frame->GetBoard()->GetFirstFootprint()->ClearFlags();
610
611 frame()->ClearUndoRedoList();
612
613 // Update the save items if needed.
614 if( is_last_fp_from_brd )
615 {
616 m_frame->ReCreateMenuBar();
617 m_frame->ReCreateHToolbar();
618 }
619
620 m_toolMgr->RunAction( ACTIONS::zoomFitScreen );
621 m_frame->OnModify();
622 return 0;
623}
624
625
627{
628 if( FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint() )
629 m_frame->ExportFootprint( fp );
630
631 return 0;
632}
633
634
636{
637 FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
638
639 if( !fp )
640 {
641 wxMessageBox( _( "No footprint to export" ) );
642 return 0;
643 }
644
645 wxFileName fn( fp->GetFPID().GetLibItemName() );
646 fn.SetExt( FILEEXT::SVGFileExtension );
647
648 wxString pro_dir = wxPathOnly( m_frame->Prj().GetProjectFullName() );
649
650 wxString fullFileName = wxFileSelector( _( "SVG File Name" ), pro_dir, fn.GetFullName(), FILEEXT::SVGFileExtension,
651 FILEEXT::SVGFileWildcard(), wxFD_SAVE, m_frame );
652
653 if( !fullFileName.IsEmpty() )
654 {
655 PCB_PLOT_PARAMS plotOpts;
656 plotOpts.SetFormat( PLOT_FORMAT::SVG );
657 plotOpts.SetColorSettings( m_frame->GetColorSettings() );
658 plotOpts.SetScale( 1.0 );
659 plotOpts.SetAutoScale( false );
660
662
663 PlotFootprintToSVG( *fp, m_frame->Prj(), nullptr, plotOpts, layersToPlot, LSEQ(), fullFileName );
664 }
665
666 return 0;
667}
668
669
671{
672 wxCHECK( m_frame, 0 );
673
674 const wxString libNickname = m_frame->GetTargetFPID().GetUniStringLibNickname();
675
676 if( libNickname.IsEmpty() )
677 {
678 m_frame->ShowInfoBarError( _( "Select a library to compare against another." ) );
679 return 0;
680 }
681
683
684 wxCHECK( adapter, 0 );
685
686 std::optional<LIBRARY_TABLE_ROW*> row = adapter->GetRow( libNickname );
687
688 if( !row )
689 {
690 m_frame->ShowInfoBarError( wxString::Format( _( "Library '%s' is not in the footprint "
691 "library table." ),
692 libNickname ) );
693 return 0;
694 }
695
696 // MakeAbsolute so relative table URIs resolve from the project dir, not
697 // the process cwd.
698 wxFileName currentFn = wxFileName::DirName(
699 LIBRARY_MANAGER::GetFullURI( *row, /*aSubstituted=*/true ) );
700 currentFn.MakeAbsolute();
701 const wxString currentPath = currentFn.GetPath();
702
703 wxDirDialog dlg( m_frame, _( "Choose .pretty Folder to Compare With" ), wxEmptyString,
704 wxDD_DIR_MUST_EXIST );
705
706 if( dlg.ShowModal() != wxID_OK )
707 return 0;
708
709 wxFileName otherFn = wxFileName::DirName( dlg.GetPath() );
710 otherFn.MakeAbsolute();
711
712 if( otherFn.GetDirs().IsEmpty()
713 || !otherFn.GetDirs().Last().EndsWith( wxS( ".pretty" ) ) )
714 {
715 m_frame->ShowInfoBarError(
716 _( "Select a KiCad footprint library folder (ends with .pretty)." ) );
717 return 0;
718 }
719
720 if( otherFn.SameAs( currentFn ) )
721 {
722 m_frame->ShowInfoBarError(
723 _( "Select a different .pretty folder than the active library." ) );
724 return 0;
725 }
726
727 const wxString otherPath = otherFn.GetPath();
728
729 std::vector<std::unique_ptr<FOOTPRINT>> beforeStorage;
730 std::vector<std::unique_ptr<FOOTPRINT>> afterStorage;
733
734 auto load =
735 [&]( const wxString& aPath,
736 std::vector<std::unique_ptr<FOOTPRINT>>& aOwners,
738 {
739 try
740 {
741 auto loaded = KICAD_DIFF::FP_LIB_DIFFER::LoadLibrary( aPath );
742 aOwners = std::move( loaded.first );
743 aMap = std::move( loaded.second );
744 return true;
745 }
746 catch( const IO_ERROR& ioe )
747 {
748 m_frame->ShowInfoBarError(
749 wxString::Format( _( "Failed to load %s: %s" ), aPath, ioe.What() ) );
750 }
751 catch( const std::exception& e )
752 {
753 m_frame->ShowInfoBarError(
754 wxString::Format( _( "Failed to load %s: %s" ), aPath,
755 wxString::FromUTF8( e.what() ) ) );
756 }
757
758 return false;
759 };
760
761 if( !load( currentPath, beforeStorage, beforeMap ) )
762 return 0;
763
764 if( !load( otherPath, afterStorage, afterMap ) )
765 return 0;
766
767 KICAD_DIFF::FP_LIB_DIFFER differ( beforeMap, afterMap, otherPath );
769
770 DIALOG_KICAD_DIFF dlgDiff( m_frame, currentPath, otherPath, result );
771 dlgDiff.ShowModal();
772
773 return 0;
774}
775
776
778{
779 // No check for multi selection since the context menu option must be hidden in that case
780 LIB_ID libId = m_frame->GetTargetFPID();
781
782 wxString libName = libId.GetLibNickname();
783 wxString libItemName = libId.GetLibItemName();
784 wxString path = wxEmptyString;
785
787 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
788
789 if( !optUri )
790 return 0;
791
792 path = *optUri;
793
794 wxString fileExt = wxEmptyString;
795
796 // If selection is footprint
797 if( !libItemName.IsEmpty() )
799
800 wxFileName fileName( path, libItemName, fileExt );
801 wxString explorerCommand;
802
803 if( COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
804 explorerCommand = cfg->m_System.file_explorer;
805
806 if( explorerCommand.IsEmpty() )
807 {
808 path = fileName.GetFullPath().BeforeLast( wxFileName::GetPathSeparator() );
809
810 if( !path.IsEmpty() && wxDirExists( path ) )
812
813 return 0;
814 }
815
816 if( !explorerCommand.EndsWith( "%F" ) )
817 {
818 wxMessageBox( _( "Missing/malformed file explorer argument '%F' in common settings." ) );
819 return 0;
820 }
821
822 wxString escapedFilePath = fileName.GetFullPath();
823 escapedFilePath.Replace( wxS( "\"" ), wxS( "_" ) );
824
825 wxString fileArg = wxEmptyString;
826 fileArg << '"' << escapedFilePath << '"';
827
828 explorerCommand.Replace( wxT( "%F" ), fileArg );
829
830 if( !explorerCommand.IsEmpty() )
831 wxExecute( explorerCommand );
832
833 return 0;
834}
835
836
838{
839 wxString fullEditorName = Pgm().GetTextEditor();
840
841 if( fullEditorName.IsEmpty() )
842 {
843 wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
844 return 0;
845 }
846
847 // No check for multi selection since the context menu option must be hidden in that case
848 LIB_ID libId = m_frame->GetLibTree()->GetSelectedLibId();
849
851
852 wxString libName = libId.GetLibNickname();
853 wxString libItemName = wxEmptyString;
854
855 std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
856
857 if( !optUri )
858 return 0;
859
860 libItemName = *optUri;
861 libItemName << wxFileName::GetPathSeparator();
862 libItemName << libId.GetLibItemName();
863 libItemName << '.' + FILEEXT::KiCadFootprintFileExtension;
864
865 if( !wxFileName::FileExists( libItemName ) )
866 return 0;
867
868 ExecuteFile( fullEditorName, libItemName.wc_str(), nullptr, false );
869
870 return 0;
871}
872
873
875{
876 if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
877 {
878 std::optional<wxString> url = GetFootprintDocumentationURL( *footprint );
879
880 if( !url.has_value() )
881 {
882 frame()->ShowInfoBarMsg( _( "No datasheet found in the footprint." ) );
883 }
884 else
885 {
886 // Only absolute URLs are supported
887 SEARCH_STACK* searchStack = nullptr;
888 GetAssociatedDocument( m_frame, *url, &m_frame->Prj(), searchStack,
889 { m_frame->GetBoard(), footprint } );
890 }
891 }
892 return 0;
893}
894
895
897{
898 m_frame->LoadFootprintFromLibrary( m_frame->GetLibTree()->GetSelectedLibId() );
899 return 0;
900}
901
902
904{
905 FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint();
906
907 if( !footprint || !m_frame->IsCurrentFPFromBoard() )
908 {
909 wxBell();
910 return 0;
911 }
912
913 m_frame->LoadFootprintFromLibrary( footprint->GetFPID() );
914
915 if( !m_frame->IsLibraryTreeShown() )
916 m_frame->ToggleLibraryTree();
917
918 return 0;
919}
920
921
923{
924 m_frame->ToggleLayersManager();
925 return 0;
926}
927
928
930{
931 m_frame->ToggleProperties();
932 return 0;
933}
934
935
937{
938 // Check if called from tree context menu
940 {
941 LIB_ID treeLibId = m_frame->GetLibTree()->GetSelectedLibId();
942
943 // Check if a different footprint is selected in the tree
944 if( treeLibId.IsValid()
945 && ( !m_frame->GetBoard()->GetFirstFootprint()
946 || m_frame->GetBoard()->GetFirstFootprint()->GetFPID() != treeLibId ) )
947 {
948 // Edit properties directly from library without loading to canvas
950 return 0;
951 }
952 }
953
954 if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
955 {
956 getEditFrame<FOOTPRINT_EDIT_FRAME>()->OnEditItemRequest( footprint );
957 m_frame->GetCanvas()->Refresh();
958 }
959
960 return 0;
961}
962
963
965{
966 // Load the footprint from the library (without adding it to the canvas)
967 FOOTPRINT* libraryFootprint = m_frame->LoadFootprint( aLibId );
968
969 if( !libraryFootprint )
970 return;
971
972 // Create a temporary board to hold the footprint (required by the dialog)
973 std::unique_ptr<BOARD> tempBoard( new BOARD() );
974
975 // Set up the temp board with the current project and board settings.
976 // Use reference-only mode to avoid modifying the project's settings.
977 tempBoard->SetDesignSettings( m_frame->GetBoard()->GetDesignSettings() );
978 tempBoard->SetProject( &m_frame->Prj(), true );
979 tempBoard->SetBoardUse( BOARD_USE::FPHOLDER );
980 tempBoard->SynchronizeProperties();
981
982 // Create a copy to work with and add it to the temporary board
983 FOOTPRINT* tempFootprint = static_cast<FOOTPRINT*>( libraryFootprint->Clone() );
984 delete libraryFootprint;
985
986 tempBoard->Add( tempFootprint );
987 tempFootprint->SetParent( tempBoard.get() );
988
989 LIB_ID oldFPID = tempFootprint->GetFPID();
990
991 // Open the properties dialog
992 DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( m_frame, tempFootprint );
993
994 if( dialog.ShowQuasiModal() != wxID_OK )
995 return;
996
997 // Remove from temporary board before saving (to avoid double-delete)
998 tempBoard->Remove( tempFootprint );
999
1000 // Save the modified footprint back to the library
1002 wxString libName = aLibId.GetLibNickname();
1003
1004 try
1005 {
1006 adapter->SaveFootprint( libName, tempFootprint, true );
1007
1008 // Update the tree view
1009 wxDataViewItem treeItem = m_frame->GetLibTreeAdapter()->FindItem( oldFPID );
1010 m_frame->UpdateLibraryTree( treeItem, tempFootprint );
1011 m_frame->SyncLibraryTree( true );
1012
1013 // Clean up
1014 delete tempFootprint;
1015 }
1016 catch( const IO_ERROR& ioe )
1017 {
1018 delete tempFootprint;
1019 DisplayError( m_frame, ioe.What() );
1020 }
1021}
1022
1023
1025{
1027 DIALOG_CLEANUP_GRAPHICS dlg( editFrame, true );
1028
1029 dlg.ShowModal();
1030 return 0;
1031}
1032
1033
1035{
1036 if( !m_checkerDialog )
1037 {
1039 m_checkerDialog->Show( true );
1040 }
1041 else // The dialog is just not visible (because the user has double clicked on an error item)
1042 {
1043 m_checkerDialog->Show( true );
1044 }
1045
1046 return 0;
1047}
1048
1049
1051{
1052 const FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint();
1053
1054 if( !footprint )
1055 return 0;
1056
1057 DIALOG_FOOTPRINT_USERS dlg( m_frame, m_frame->Kiway(), m_frame->GetLoadedFPID(), footprint->GetPinCount() );
1058
1059 dlg.ShowModal();
1060 return 0;
1061}
1062
1063
1065{
1066 if( !m_checkerDialog )
1068
1069 if( !m_checkerDialog->IsShownOnScreen() )
1070 m_checkerDialog->Show( true );
1071
1072 m_checkerDialog->SelectMarker( aMarker );
1073}
1074
1075
1077{
1078 if( m_checkerDialog )
1079 {
1080 m_checkerDialog->Destroy();
1081 m_checkerDialog = nullptr;
1082 }
1083}
1084
1085
1087{
1088 FOOTPRINT* footprint = board()->Footprints().front();
1089 int errors = 0;
1090 wxString details;
1091
1092 // Repair duplicate IDs and missing nets.
1093 std::set<KIID> ids;
1094 int duplicates = 0;
1095
1096 auto processItem =
1097 [&]( EDA_ITEM* aItem )
1098 {
1099 if( ids.count( aItem->m_Uuid ) )
1100 {
1101 duplicates++;
1102 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
1103 boardItem->ResetUuid();
1104 }
1105
1106 ids.insert( aItem->m_Uuid );
1107 };
1108
1109 // Footprint IDs are the most important, so give them the first crack at "claiming" a
1110 // particular KIID.
1111
1112 processItem( footprint );
1113
1114 // After that the principal use is for DRC marker pointers, which are most likely to pads.
1115
1116 for( PAD* pad : footprint->Pads() )
1117 processItem( pad );
1118
1119 // From here out I don't think order matters much.
1120
1121 processItem( &footprint->Reference() );
1122 processItem( &footprint->Value() );
1123
1124 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1125 processItem( item );
1126
1127 for( ZONE* zone : footprint->Zones() )
1128 processItem( zone );
1129
1130 for( PCB_GROUP* group : footprint->Groups() )
1131 processItem( group );
1132
1133 if( duplicates )
1134 {
1135 errors += duplicates;
1136 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
1137 }
1138
1139 if( errors )
1140 {
1141 m_frame->OnModify();
1142
1143 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
1144 DisplayInfoMessage( m_frame, msg, details );
1145 }
1146 else
1147 {
1148 DisplayInfoMessage( m_frame, _( "No footprint problems found." ) );
1149 }
1150
1151 return 0;
1152}
1153
1154
1155// The appearance panel also claims Ctrl+Tab for layer-preset cycling, so it wins when focused.
1157{
1158 wxWindow* appearance = aFrame->GetAppearancePanel();
1159
1160 if( !appearance )
1161 return false;
1162
1163 for( wxWindow* focus = wxWindow::FindFocus(); focus; focus = focus->GetParent() )
1164 {
1165 if( focus == appearance )
1166 return true;
1167 }
1168
1169 return false;
1170}
1171
1172
1174{
1176 return 0;
1177
1178 m_frame->AdvanceFootprintTab( true );
1179 return 0;
1180}
1181
1182
1184{
1186 return 0;
1187
1188 m_frame->AdvanceFootprintTab( false );
1189 return 0;
1190}
1191
1192
1194{
1195 m_frame->CloseActiveFootprintTab();
1196 return 0;
1197}
1198
1199
1201{
1202 if( m_frame->GetTargetFPID().GetLibNickname().empty() )
1203 return 0;
1204
1205 if( m_frame->HasModifiedFootprintTabs() )
1206 {
1207 DisplayInfoMessage( m_frame, _( "Save or discard the changes in all modified footprint tabs before opening "
1208 "the Footprint Fields Table." ) );
1209 return 0;
1210 }
1211
1213
1214 dlg.ShowModal();
1215 return 0;
1216}
1217
1218
1220{
1221 // clang-format off
1224 PCB_ACTIONS::createFootprint.MakeEvent() );
1231
1237
1245
1249
1252
1256
1260
1264 // clang-format on
1265
1266 // Line modes for the footprint editor: explicit modes, next-mode, and toolbar sync
1272}
1273
1275{
1276 LEADER_MODE mode = aEvent.Parameter<LEADER_MODE>();
1277 GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode = mode;
1278 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1280 return 0;
1281}
1282
1284{
1286
1287 if( !f )
1288 return 0;
1289
1290 LEADER_MODE mode = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode;
1291
1292 switch( mode )
1293 {
1296 default:
1298 }
1299
1300 return 0;
1301}
@ FPHOLDER
Definition board.h:403
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:264
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:85
void BuildListOfNets()
Definition board.h:1180
const FOOTPRINTS & Footprints() const
Definition board.h:465
Shows the symbols that use a footprint with some switchable match categories.
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.
void CrossProbe(const PCB_MARKER *aMarker)
int ChangeLineMode(const TOOL_EVENT &aEvent)
int ShowFootprintUsers(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:418
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:417
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 showFootprintUsers
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 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:233
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.