KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/files.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) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2023 CERN (www.cern.ch)
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include <string>
24#include <vector>
25
26#include <advanced_config.h>
27#include <confirm.h>
28#include <kidialog.h>
29#include <core/arraydim.h>
30#include <core/profile.h>
31#include <thread_pool.h>
32#include <gestfich.h>
33#include <local_history.h>
34#include <pcb_edit_frame.h>
36#include <board_loader.h>
41#include <import_net_names.h>
42#include <kiface_base.h>
43#include <macros.h>
44#include <trace_helpers.h>
46#include <lockfile.h>
48#include <pcbnew_id.h>
50#include <tool/tool_manager.h>
51#include <board.h>
52#include <footprint.h>
53#include <collectors.h>
55#include <kiplatform/app.h>
56#include <kiplatform/ui.h>
58#include <widgets/wx_infobar.h>
61#include <paths.h>
62#include <pgm_base.h>
64#include <project_pcb.h>
68#include <pcb_io/pcb_io_mgr.h>
76#include <tools/pcb_actions.h>
79#include <board_commit.h>
80#include <reporter.h>
81#include <zone_filler.h>
83#include <widgets/kistatusbar.h>
85#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
86#include <kiplatform/io.h>
87
88#include <wx/stdpaths.h>
89#include <wx/ffile.h>
90#include <wx/filedlg.h>
91#include <wx/txtstrm.h>
92#include <wx/wfstream.h>
93#include <wx/zipstrm.h>
94#include <wx/dir.h>
95
97
98//#define USE_INSTRUMENTATION 1
99#define USE_INSTRUMENTATION 0
100
101static const wxChar* const traceAllegroPerf = wxT( "KICAD_ALLEGRO_PERF" );
102
103
113bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 )
114{
115 std::vector<IO_BASE::IO_FILE_DESC> descriptions;
116
117 for( const auto& plugin : PCB_IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins() )
118 {
119 bool isKiCad = plugin.m_type == PCB_IO_MGR::KICAD_SEXP || plugin.m_type == PCB_IO_MGR::LEGACY;
120
121 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
122 continue;
123
124 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
125 continue;
126
127 IO_RELEASER<PCB_IO> pi( plugin.m_createFunc() );
128 wxCHECK( pi, false );
129
130 const IO_BASE::IO_FILE_DESC& desc = pi->GetBoardFileDesc();
131
132 if( desc.m_FileExtensions.empty() || !desc.m_CanRead )
133 continue;
134
135 descriptions.emplace_back( desc );
136 }
137
138 wxString fileFiltersStr;
139 std::vector<std::string> allExtensions;
140 std::set<wxString> allWildcardsSet;
141
142 for( const IO_BASE::IO_FILE_DESC& desc : descriptions )
143 {
144 if( !fileFiltersStr.IsEmpty() )
145 fileFiltersStr += wxChar( '|' );
146
147 fileFiltersStr += desc.FileFilter();
148
149 for( const std::string& ext : desc.m_FileExtensions )
150 {
151 allExtensions.emplace_back( ext );
152 allWildcardsSet.insert( wxT( "*." ) + formatWildcardExt( ext ) + wxT( ";" ) );
153 }
154 }
155
156 wxString allWildcardsStr;
157
158 for( const wxString& wildcard : allWildcardsSet )
159 allWildcardsStr << wildcard;
160
161 if( aCtl & KICTL_KICAD_ONLY )
162 {
163 fileFiltersStr = _( "All KiCad Board Files" ) + AddFileExtListToFilter( allExtensions );
164 }
165 else
166 {
167 fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
168 + fileFiltersStr;
169 }
170
171 wxFileName fileName( *aFileName );
172 wxString path;
173 wxString name;
174
175 if( fileName.FileExists() )
176 {
177 path = fileName.GetPath();
178 name = fileName.GetFullName();
179 }
180 else
181 {
182 path = aParent->GetMruPath();
183
184 if( path.IsEmpty() )
186 // leave name empty
187 }
188
189 bool kicadFormat = ( aCtl & KICTL_KICAD_ONLY );
190
191 wxFileDialog dlg( aParent, kicadFormat ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
192 path, name, fileFiltersStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
193
194 FILEDLG_IMPORT_NON_KICAD importOptions( aParent->config()->m_System.show_import_issues );
195
196 if( !kicadFormat )
197 dlg.SetCustomizeHook( importOptions );
198
200
201 if( dlg.ShowModal() == wxID_OK )
202 {
203 *aFileName = dlg.GetPath();
204 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
205
206 if( !kicadFormat )
207 aParent->config()->m_System.show_import_issues = importOptions.GetShowIssues();
208
209 return true;
210 }
211 else
212 {
213 return false;
214 }
215}
216
217
227bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
228{
229 wxString wildcard = FILEEXT::PcbFileWildcard();
230 wxFileName fn = *aFileName;
231
233
234 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
235 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
236
237// Add a "Create a project" checkbox in standalone mode and one isn't loaded
238 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
239
240 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
241 dlg.SetCustomizeHook( newProjectHook );
242
244
245 if( dlg.ShowModal() != wxID_OK )
246 return false;
247
248 *aFileName = dlg.GetPath();
249 *aFileName = EnsureFileExtension( *aFileName, FILEEXT::KiCadPcbFileExtension );
250
251 if( newProjectHook.IsAttachedToDialog() )
252 *aCreateProject = newProjectHook.GetCreateNewProject();
253 else if( !aParent->Prj().IsNullProject() )
254 *aCreateProject = true;
255
256 return true;
257}
258
259
260void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
261{
262 wxString filename = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
263
264 if( !filename.IsEmpty() )
265 {
266 if( !wxFileName::IsFileReadable( filename ) )
267 {
268 if( !AskLoadBoardFileName( this, &filename, KICTL_KICAD_ONLY ) )
269 return;
270 }
271
272 OpenProjectFiles( std::vector<wxString>( 1, filename ), KICTL_KICAD_ONLY );
273 }
274}
275
276
277void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
278{
280}
281
282
284{
285 // Only standalone mode can directly load a new document
286 if( !Kiface().IsSingle() )
287 return false;
288
289 int open_ctl = KICTL_KICAD_ONLY;
290 wxString fileName = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
291
292 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
293 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
294
295 return 0;
296}
297
298
300{
301 // Note: we explicitly allow this even if not in standalone mode for now, even though it is dangerous.
302 int open_ctl = KICTL_NONKICAD_ONLY;
303 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
304
305 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
306 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
307
308 return 0;
309}
310
311
313{
314 wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
315
316 if( !IsOK( m_frame, wxString::Format( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() ) ) )
317 return false;
318
319 m_frame->GetScreen()->SetContentModified( false ); // do not prompt the user for changes
320
321 m_frame->ReleaseFile();
322
323 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ), KICTL_REVERT );
324
325 return 0;
326}
327
328
330{
331 // Only standalone mode can directly load a new document
332 if( !Kiface().IsSingle() )
333 return false;
334
335 if( !m_frame->CloseFootprintFieldsTableDialog() )
336 return false;
337
338 if( m_frame->IsContentModified() )
339 {
340 wxFileName fileName = m_frame->GetBoard()->GetFileName();
341 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
342 "continuing?" );
343
344 if( !HandleUnsavedChanges( m_frame, wxString::Format( saveMsg, fileName.GetFullName() ),
345 [&]()->bool
346 {
347 return m_frame->SaveBoard();
348 } ) )
349 {
350 return false;
351 }
352 }
353 else if( !m_frame->GetBoard()->IsEmpty() )
354 {
355 if( !IsOK( m_frame, _( "Current Board will be closed. Continue?" ) ) )
356 return false;
357 }
358
359 m_frame->SaveProjectLocalSettings();
360
361 m_frame->GetBoard()->ClearProject();
362 m_frame->GetSettingsManager()->UnloadProject( &m_frame->Prj() );
363
364 if( !m_frame->Clear_Pcb( false ) )
365 return false;
366
367 m_frame->LoadProjectSettings();
368 m_frame->LoadDrawingSheet();
369
370 m_frame->OnBoardLoaded();
371 m_frame->OnModify();
372
373 return 0;
374}
375
376
377bool PCB_EDIT_FRAME::SaveBoard( bool aSaveAs, bool aSaveCopy )
378{
379 if( !aSaveAs )
380 {
381 if( !GetBoard()->GetFileName().IsEmpty() )
382 {
383 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
384 {
385 m_autoSaveRequired = false;
386 return true;
387 }
388
389 return false;
390 }
391 }
392
393 wxString orig_name;
394
395 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
396
397 if( orig_name.IsEmpty() )
398 orig_name = NAMELESS_PROJECT;
399
400 wxFileName savePath( Prj().GetProjectFullName() );
401
402 if( !savePath.IsOk() || !savePath.IsDirWritable() )
403 {
404 savePath = GetMruPath();
405
406 if( !savePath.IsOk() || !savePath.IsDirWritable() )
408 }
409
410 wxFileName fn( savePath.GetPath(), orig_name, FILEEXT::KiCadPcbFileExtension );
411 wxString filename = fn.GetFullPath();
412 bool createProject = false;
413 bool success = false;
414
415 if( AskSaveBoardFileName( this, &filename, &createProject ) )
416 {
417 if( aSaveCopy )
418 {
419 success = SavePcbCopy( EnsureFileExtension( filename, FILEEXT::KiCadPcbFileExtension ), createProject );
420 }
421 else
422 {
423 success = SavePcbFile( filename, aSaveAs, createProject );
424
425 if( success )
426 m_autoSaveRequired = false;
427 }
428 }
429
430 return success;
431}
432
433
434int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard, bool aShowUserMsg )
435{
436 PCB_LAYER_COLLECTOR collector;
437
438 collector.SetLayerId( Edge_Cuts );
439 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
440
441 int edgeWidth = -1;
442 bool mixed = false;
443
444 for( int i = 0; i < collector.GetCount(); i++ )
445 {
446 if( collector[i]->Type() == PCB_SHAPE_T )
447 {
448 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
449
450 if( edgeWidth != -1 && edgeWidth != itemWidth )
451 {
452 mixed = true;
453 edgeWidth = std::max( edgeWidth, itemWidth );
454 }
455 else
456 {
457 edgeWidth = itemWidth;
458 }
459 }
460 }
461
462 if( mixed && aShowUserMsg )
463 {
464 // If they had different widths then we can't ensure that fills will be the same.
465 DisplayInfoMessage( this,
466 _( "If the zones on this board are refilled the Copper Edge "
467 "Clearance setting will be used (see Board Setup > Design "
468 "Rules > Constraints).\n This may result in different fills "
469 "from previous KiCad versions which used the line thicknesses "
470 "of the board boundary on the Edge Cuts layer." ) );
471 }
472
473 return std::max( 0, edgeWidth / 2 );
474}
475
476
477bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
478{
479 // This is for python:
480 if( aFileSet.size() != 1 )
481 {
482 DisplayError( this, wxString::Format( "Pcbnew:%s() takes a single filename", __func__ ) );
483 return false;
484 }
485
486 wxString fullFileName( aFileSet[0] );
487 wxFileName wx_filename( fullFileName );
488 wxString msg;
489
490 if( Kiface().IsSingle() )
492
493 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
494 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
495
496 std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
497
498 if( !lock->Valid() )
499 {
500 // If project-level lock override was already granted, silently override this file's lock
501 if( Prj().IsLockOverrideGranted() )
502 {
503 lock->OverrideLock();
504 }
505 else
506 {
507 msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ),
508 wx_filename.GetFullName(),
509 lock->GetUsername(),
510 lock->GetHostname() );
511
512 if( !AskOverrideLock( this, msg ) )
513 return false;
514
515 lock->OverrideLock();
516 }
517 }
518
520 return false;
521
522 if( IsContentModified() )
523 {
524 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
525 [&]() -> bool
526 {
527 return SavePcbFile( GetBoard()->GetFileName() );
528 } ) )
529 {
530 return false;
531 }
532 }
533
534 wxFileName pro = fullFileName;
535 pro.SetExt( FILEEXT::ProjectFileExtension );
536
537 bool is_new = !wxFileName::IsFileReadable( fullFileName );
538
539 wxString previousBoardFileName = GetBoard() ? GetBoard()->GetFileName() : wxString();
540
541 // If its a non-existent PCB and caller thinks it exists
542 if( is_new && !( aCtl & KICTL_CREATE ) )
543 {
544 // notify user that fullFileName does not exist, ask if user wants to create it.
545 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
546
547 if( !IsOK( this, msg ) )
548 return false;
549 }
550
551 // Get rid of any existing warnings about the old board
552 GetInfoBar()->Dismiss();
553
554 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
555 statusBar->ClearWarningMessages( "load" );
556
557 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Create PCB" ) : _( "Load PCB" ), 1,
558 PR_CAN_ABORT );
559 WX_STRING_REPORTER loadReporter;
560 LOAD_INFO_REPORTER_SCOPE loadReporterScope( &loadReporter );
561
562 // No save prompt (we already prompted above), and only reset to a new blank board if new
563 Clear_Pcb( false, !is_new );
564
566
567 if( !is_new )
568 pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
569
570 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
571 {
572 progressReporter.Hide();
573 DisplayErrorMessage( this, _( "File format is not supported" ), wxEmptyString );
574 return false;
575 }
576
577 bool converted = pluginType != PCB_IO_MGR::LEGACY && pluginType != PCB_IO_MGR::KICAD_SEXP;
578
579 // Loading a project should only be done under carefully considered circumstances.
580
581 // The calling code should know not to ask me here to change projects unless
582 // it knows what consequences that will have on other KIFACEs running and using
583 // this same PROJECT. It can be very harmful if that calling code is stupid.
585 bool setProject;
586
587 if( Kiface().IsSingle() || !( aCtl & KICTL_NONKICAD_ONLY ) )
588 setProject = pro.GetFullPath() != mgr->Prj().GetProjectFullName();
589 else
590 setProject = Prj().GetProjectFullName().IsEmpty();
591
592 if( setProject )
593 {
594 // calls SaveProject
596
598 mgr->UnloadProject( &mgr->Prj() );
599
600 mgr->LoadProject( pro.GetFullPath() );
601
602 if( Kiface().IsSingle() )
603 {
604 // Standalone opens can switch to a different project. Preload libraries after the
605 // project switch so the board load sees project-local library tables.
608 }
609
610 // Do not allow saving a project if one doesn't exist. This normally happens if we are
611 // opening a board that has been moved from its project folder.
612 // For converted projects, we don't want to set the read-only flag because we want a
613 // project to be saved for the new file in case things like netclasses got migrated.
614 Prj().SetReadOnly( !pro.Exists() && !converted );
615 }
616
617 // Crash-recovery: when zip-format autosave is active, look for autosave files newer than
618 // the saved board and offer to recover them before the load happens.
619 if( !is_new )
620 CheckForAutosaveFiles( wx_filename.GetPath(), { FILEEXT::KiCadPcbFileExtension } );
621
622 if( is_new )
623 {
624 // Link the existing blank board to the new project
625 GetBoard()->SetProject( &Prj() );
626
627 GetBoard()->SetFileName( fullFileName );
628
629 OnModify();
630 }
631 else
632 {
633 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
634 bool failedLoad = false;
635
636 // importer template footprints, captured at load for reconciliation
637 std::vector<std::unique_ptr<FOOTPRINT>> importedLibFootprints;
638
639 try
640 {
641 std::map<std::string, UTF8> props;
642
644 props.insert( m_importProperties->begin(), m_importProperties->end() );
645
646 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
647 props["page_width"] = std::to_string( GetPageSizeIU().x );
648 props["page_height"] = std::to_string( GetPageSizeIU().y );
649
650#if USE_INSTRUMENTATION
651 // measure the time to load a BOARD.
652 int64_t startTime = GetRunningMicroSecs();
653#endif
654 BOARD_LOADER::OPTIONS loaderOptions;
655 loaderOptions.properties = &props;
656 loaderOptions.progress_reporter = &progressReporter;
657 loaderOptions.reporter = config()->m_System.show_import_issues
658 ? static_cast<REPORTER*>( &loadReporter )
659 : static_cast<REPORTER*>( &NULL_REPORTER::GetInstance() );
660 loaderOptions.initialize_after_load = false;
661
662 if( aCtl & KICTL_IMPORT_LIB )
663 {
664 loaderOptions.post_load_hook =
665 [&]( PCB_IO& aPlugin )
666 {
667 try
668 {
669 for( FOOTPRINT* fp : aPlugin.GetImportedCachedLibraryFootprints() )
670 importedLibFootprints.emplace_back( fp );
671 }
672 catch( const IO_ERROR& )
673 {
674 // no cached library, reconcile from placed only
675 }
676 };
677 }
678
679 loaderOptions.plugin_configurator =
680 [&]( PCB_IO& aPlugin )
681 {
682 if( LAYER_MAPPABLE_PLUGIN* mappable_pi =
683 dynamic_cast<LAYER_MAPPABLE_PLUGIN*>( &aPlugin ) )
684 {
685 if( !ADVANCED_CFG::GetCfg().m_ImportSkipLayerMapping )
686 {
687 const auto layerMapCallback =
688 [this]( const std::vector<INPUT_LAYER_DESC>& aLayers )
689 {
690 return DIALOG_MAP_LAYERS::RunModal( this, aLayers );
691 };
692
693 mappable_pi->RegisterCallback( layerMapCallback );
694 }
695 }
696
697 if( PROJECT_CHOOSER_PLUGIN* chooser_pi =
698 dynamic_cast<PROJECT_CHOOSER_PLUGIN*>( &aPlugin ) )
699 {
700 const auto chooseProjectCallback =
701 [this]( const std::vector<IMPORT_PROJECT_DESC>& aProjects )
702 {
703 return DIALOG_IMPORT_CHOOSE_PROJECT::RunModal( this, aProjects );
704 };
705
706 chooser_pi->RegisterCallback( chooseProjectCallback );
707 }
708
709 aPlugin.SetQueryUserCallback(
710 [&]( wxString aTitle, int aIcon, wxString aMessage,
711 wxString aAction ) -> bool
712 {
713 KIDIALOG dlg( nullptr, aMessage, aTitle,
714 wxOK | wxCANCEL | aIcon );
715
716 if( !aAction.IsEmpty() )
717 dlg.SetOKLabel( aAction );
718
719 dlg.DoNotShowCheckbox( aMessage, 0 );
720
721 return dlg.ShowModal() == wxID_OK;
722 } );
723 };
724
725 std::unique_ptr<BOARD> loaded =
726 BOARD_LOADER::Load( fullFileName, pluginType, &Prj(), loaderOptions );
727
728 if( loaded && props.count( IMPORT_PROJ_PROPS::NET_NAME_MAP ) )
729 {
730 std::optional<std::map<wxString, wxString>> netNames =
732 props.at( IMPORT_PROJ_PROPS::NET_NAME_MAP ).wx_str() );
733
734 if( !netNames )
735 THROW_IO_ERROR( _( "Invalid imported net-name map." ) );
736
737 if( !ApplyImportedNetNameMap( *loaded, *netNames, loadReporter ) )
738 THROW_IO_ERROR( _( "Cannot apply imported net-name map to the board." ) );
739 }
740
741 loadedBoard = loaded.release();
742
743#if USE_INSTRUMENTATION
744 int64_t stopTime = GetRunningMicroSecs();
745 printf( "PCB_IO::Load(): %u usecs\n", stopTime - startTime );
746#endif
747 }
748 catch( const FUTURE_FORMAT_ERROR& ffe )
749 {
750 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
751 progressReporter.Hide();
752 DisplayErrorMessage( this, msg, ffe.Problem() );
753
754 failedLoad = true;
755 }
756 catch( const IO_CANCELLED& )
757 {
758 // A user-cancelled load is not an error; abandon it without a dialog.
759 failedLoad = true;
760 }
761 catch( const IO_ERROR& ioe )
762 {
763 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
764 progressReporter.Hide();
765 DisplayErrorMessage( this, msg, ioe.What() );
766
767 failedLoad = true;
768 }
769 catch( const std::bad_alloc& )
770 {
771 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
772 progressReporter.Hide();
773 DisplayErrorMessage( this, msg, wxEmptyString );
774
775 failedLoad = true;
776 }
777
778 if( failedLoad || !loadedBoard )
779 {
780 // We didn't create a new blank board above, so do that now
781 Clear_Pcb( false );
782
783 // Show any messages collected before the failure
784 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
785 statusBar->AddWarningMessages( "load", loadReporter.GetMessages() );
786
787 return false;
788 }
789
790 if( converted && GetPcbNewSettings()->m_ImportKeepKiCadLayerNames )
791 {
792 for( PCB_LAYER_ID layer : loadedBoard->GetEnabledLayers().Seq() )
793 loadedBoard->SetLayerName( layer, wxEmptyString );
794 }
795
796 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
797 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
798 // compiled.
799 Raise();
800
801 // Skip (possibly expensive) connectivity build here; we build it below after load
802 progressReporter.AddPhases( 1 );
803 progressReporter.AdvancePhase( _( "Finalizing board" ) );
804 progressReporter.KeepRefreshing();
805
806 PROF_TIMER postLoadTimer;
807 SetBoard( loadedBoard, false, &progressReporter );
808 wxLogTrace( traceAllegroPerf, wxT( "Post-load SetBoard: %.3f ms" ),
809 postLoadTimer.msecs( true ) );
810
811 if( loadedBoard->m_LegacyDesignSettingsLoaded )
812 {
813 Prj().SetReadOnly( false );
814
815 // Before we had a copper edge clearance setting, the edge line widths could be used
816 // as a kludge to control them. So if there's no setting then infer it from the
817 // edge widths.
818 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
819 {
820 // Do not show the inferred edge clearance warning dialog when loading third
821 // party boards. For some reason the dialog completely hangs all of KiCad and
822 // the imported board cannot be saved.
823 int edgeClearance = inferLegacyEdgeClearance( loadedBoard, !converted );
824 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
825 }
826
827 // On save; design settings will be removed from the board
828 loadedBoard->SetModified();
829 }
830
831 // Move legacy view settings to local project settings
832 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
833 {
835 loadedBoard->SetModified();
836 }
837
839 {
841 loadedBoard->SetModified();
842 }
843
844 if( !loadedBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
845 {
846 m_infoBar->RemoveAllButtons();
847 m_infoBar->AddCloseButton();
848 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
849 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
850 }
851
852 // we should not ask PCB_IOs to do these items:
853 loadedBoard->BuildListOfNets();
854 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildListOfNets: %.3f ms" ),
855 postLoadTimer.msecs( true ) );
856
857 progressReporter.KeepRefreshing();
858
859 m_toolManager->RunAction( PCB_ACTIONS::repairBoard, true);
860 wxLogTrace( traceAllegroPerf, wxT( "Post-load repairBoard: %.3f ms" ),
861 postLoadTimer.msecs( true ) );
862
863 progressReporter.KeepRefreshing();
864
866 wxLogTrace( traceAllegroPerf, wxT( "Post-load rehatchShapes: %.3f ms" ),
867 postLoadTimer.msecs( true ) );
868
869 progressReporter.KeepRefreshing();
870
871 if( loadedBoard->IsModified() )
872 OnModify();
873 else
874 GetScreen()->SetContentModified( false );
875
876 if( ( pluginType == PCB_IO_MGR::LEGACY )
877 || ( pluginType == PCB_IO_MGR::KICAD_SEXP
879 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
880 {
881 m_infoBar->RemoveAllButtons();
882 m_infoBar->AddCloseButton();
883 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
884 "It will be converted to the new format when saved." ),
885 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
886 }
887
888 // extract a project fp library and re-link board FPIDs so update-from-schematic works
889 if( aCtl & KICTL_IMPORT_LIB )
890 reconcileImportedFootprintLibraries( std::move( importedLibFootprints ), fullFileName );
891 }
892
893 {
894 wxString fname;
895
896 if( !previousBoardFileName.IsEmpty() && ( aCtl & KICTL_NONKICAD_ONLY ) && !setProject )
897 {
898 fname = previousBoardFileName;
899 }
900 else
901 {
902 wxFileName fn;
903
904 fn.SetPath( Prj().GetProjectPath() );
905 fn.SetName( Prj().GetProjectName() );
907
908 fname = fn.GetFullPath();
909
910 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
911 }
912
913 GetBoard()->SetFileName( fname );
914 }
915
916 // Lock the file newly opened:
917 m_file_checker.reset( lock.release() );
918
919 if( !converted )
920 UpdateFileHistory( GetBoard()->GetFileName() );
921
922 std::vector<ZONE*> toFill;
923
924 // Rebuild list of nets (full ratsnest rebuild)
925 PROF_TIMER connectivityTimer;
926 GetBoard()->BuildConnectivity( &progressReporter );
927 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildConnectivity: %.3f ms" ),
928 connectivityTimer.msecs( true ) );
929
930 // Load project settings after setting up board; some of them depend on the nets list
933 wxLogTrace( traceAllegroPerf, wxT( "Post-load LoadProjectSettings+DrawingSheet: %.3f ms" ),
934 connectivityTimer.msecs( true ) );
935
936 // Resolve DRC exclusions after project settings are loaded
937 ResolveDRCExclusions( true );
938
939 // Initialise caches used by component classes
941
942 // Initialise time domain tuning caches
944 wxLogTrace( traceAllegroPerf, wxT( "Post-load DRC+ComponentClass+Tuning caches: %.3f ms" ),
945 connectivityTimer.msecs( true ) );
946
947 // Syncs the UI (appearance panel, etc) with the loaded board and project
949 wxLogTrace( traceAllegroPerf, wxT( "Post-load OnBoardLoaded: %.3f ms" ),
950 connectivityTimer.msecs( true ) );
951 wxLogTrace( traceAllegroPerf, wxT( "=== Post-load pipeline total: %.3f ms ===" ),
952 connectivityTimer.msecs() );
953
954 // Refresh the 3D view, if any
955 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
956
957 if( draw3DFrame )
958 draw3DFrame->NewDisplay();
959#if 0 && defined(DEBUG)
960 // Output the board object tree to stdout, but please run from command prompt:
961 GetBoard()->Show( 0, std::cout );
962#endif
963
964 // from EDA_APPL which was first loaded BOARD only:
965 {
966 /* For an obscure reason the focus is lost after loading a board file
967 * when starting up the process.
968 * (seems due to the recreation of the layer manager after loading the file)
969 * Give focus to main window and Drawpanel
970 * must be done for these 2 windows (for an obscure reason ...)
971 * Linux specific
972 * This is more a workaround than a fix.
973 */
974 SetFocus();
975 GetCanvas()->SetFocus();
976 }
977
978 if( !setProject )
979 {
980 // If we didn't reload the project, we still need to call ProjectChanged() to ensure
981 // frame-specific initialization happens (like registering the autosave saver).
982 // When running under the project manager, KIWAY::ProjectChanged() was called before
983 // this frame existed, so we need to call our own ProjectChanged() now.
985 }
986
987 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
988 statusBar->AddWarningMessages( "load", loadReporter.GetMessages() );
989
990 return true;
991}
992
993
994bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
995 bool aChangeProject )
996{
997 // please, keep it simple. prompting goes elsewhere.
998 wxFileName pcbFileName = aFileName;
999
1000 if( pcbFileName.GetExt() == FILEEXT::LegacyPcbFileExtension )
1001 pcbFileName.SetExt( FILEEXT::KiCadPcbFileExtension );
1002
1003 // Write through symlinks, don't replace them
1005
1006 if( !IsWritable( pcbFileName ) )
1007 {
1008 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1009 pcbFileName.GetFullPath() );
1010
1011 DisplayError( this, msg );
1012 return false;
1013 }
1014
1015 // TODO: these will break if we ever go multi-board
1016 wxFileName projectFile( pcbFileName );
1017 wxFileName rulesFile( pcbFileName );
1018 wxString msg;
1019
1020 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1021 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1022
1023 if( projectFile.FileExists() )
1024 {
1026 }
1027 else if( aChangeProject )
1028 {
1029 Prj().SetReadOnly( false );
1030 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1031 }
1032
1033 wxFileName currentRules( GetBoard()->GetDesignRulesPath() );
1034
1035 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1036 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1037
1038 if( !msg.IsEmpty() )
1039 {
1040 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1041 rulesFile.GetFullPath() ) );
1042 }
1043
1044 if( projectFile.FileExists() )
1045 {
1046 // Save various DRC parameters, such as violation severities (which may have been
1047 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1049
1052 }
1053
1054 wxString lowerTxt;
1055
1056 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1057 // hidden or read-only. This can happen when files are synced via cloud services.
1058 if( pcbFileName.FileExists() )
1059 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1060
1061 try
1062 {
1064
1065 pi->SaveBoard( pcbFileName.GetFullPath(), *GetBoard(), nullptr );
1066 }
1067 catch( const IO_ERROR& ioe )
1068 {
1069 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1070 pcbFileName.GetFullPath(),
1071 ioe.What() ) );
1072 return false;
1073 }
1074
1075 WX_STRING_REPORTER backupReporter;
1076
1077 if( !Kiface().IsSingle() )
1078 GetSettingsManager()->TriggerBackupIfNeeded( backupReporter );
1079
1080 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1081
1082 // Update the lock in case it was a Save As
1083 LockFile( pcbFileName.GetFullPath() );
1084
1085 // Put the saved file in File History if requested
1086 if( addToHistory )
1087 UpdateFileHistory( GetBoard()->GetFileName() );
1088
1089 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1090
1091 SetStatusText( lowerTxt, 0 );
1092
1093 // Get rid of the old version conversion warning, or any other dismissable warning :)
1094 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1095 m_infoBar->Dismiss();
1096
1097 if( m_infoBar->IsShownOnScreen() && m_infoBar->HasCloseButton() )
1098 m_infoBar->Dismiss();
1099
1100 if( backupReporter.HasMessage() )
1101 {
1102 wxString backupMsg = backupReporter.GetMessages();
1103 m_infoBar->ShowMessageFor( backupMsg.Trim(), 10000, wxICON_WARNING );
1104 }
1105
1106 GetScreen()->SetContentModified( false );
1107 UpdateTitle();
1109
1110 // Capture entire project state for PCB save events. Skip when running standalone
1111 // without a project loaded - the save path can land anywhere on the filesystem and
1112 // there is no project context for a snapshot to live under.
1113 if( !Prj().IsNullProject() )
1114 {
1115 Kiway().LocalHistory().RunRegisteredSaversAndCommit( Prj().GetProjectPath(), wxS( "PCB Save" ), wxS( "pcb" ) );
1116
1117 // Drop the autosave file for the board we just persisted. Scope to the PCB
1118 // source so a concurrent open eeschema does not lose recovery data for an
1119 // unsaved schematic sheet. RunRegisteredSaversAndCommit above is a no-op when
1120 // format is ZIP; this call is conversely a no-op in INCREMENTAL mode.
1121 Kiway().LocalHistory().RemoveAutosaveFiles( Prj().GetProjectPath(), { pcbFileName.GetFullPath() } );
1122 }
1123
1124 if( m_autoSaveTimer )
1125 m_autoSaveTimer->Stop();
1126
1127 m_autoSavePending = false;
1128 m_autoSaveRequired = false;
1129 return true;
1130}
1131
1132
1133bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
1134{
1135 wxFileName pcbFileName( aFileName );
1136
1137 if( !IsWritable( pcbFileName ) )
1138 {
1139 if( !aHeadless )
1140 {
1141 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1142 pcbFileName.GetFullPath() ) );
1143 }
1144 return false;
1145 }
1146
1147 // Save various DRC parameters, such as violation severities (which may have been
1148 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1150
1153
1154 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1155 // hidden or read-only. This can happen when files are synced via cloud services.
1156 if( pcbFileName.FileExists() )
1157 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1158
1159 try
1160 {
1162
1163 wxASSERT( pcbFileName.IsAbsolute() );
1164
1165 pi->SaveBoard( pcbFileName.GetFullPath(), *GetBoard(), nullptr );
1166 }
1167 catch( const IO_ERROR& ioe )
1168 {
1169 if( !aHeadless )
1170 {
1171 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1172 pcbFileName.GetFullPath(),
1173 ioe.What() ) );
1174 }
1175
1176 return false;
1177 }
1178
1179 wxFileName projectFile( pcbFileName );
1180 wxFileName rulesFile( pcbFileName );
1181 wxString msg;
1182
1183 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1184 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1185
1186 if( aCreateProject && !projectFile.FileExists() )
1187 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1188
1189 wxFileName currentRules( GetBoard()->GetDesignRulesPath() );
1190
1191 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1192 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1193
1194 if( !msg.IsEmpty() && !aHeadless )
1195 {
1196 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1197 rulesFile.GetFullPath() ) );
1198 }
1199
1200 return true;
1201}
1202
1203
1204bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
1205 const std::map<std::string, UTF8>* aProperties )
1206{
1207 NULLER raiiNuller( (void*&) m_importProperties );
1208
1209 m_importProperties = aProperties;
1210
1212
1213 switch( fileType )
1214 {
1216 case PCB_IO_MGR::EAGLE:
1226 case PCB_IO_MGR::PADS:
1227 {
1228 int ctl = KICTL_NONKICAD_ONLY;
1229
1231 ctl |= KICTL_IMPORT_LIB;
1232
1233 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), ctl );
1234 }
1235
1236 default:
1237 return false;
1238 }
1239}
1240
1241
1243 std::vector<std::unique_ptr<FOOTPRINT>> aDefinitions, const wxString& aBoardPath )
1244{
1246
1247 ReconcileImportedFootprints( std::move( aDefinitions ), *GetBoard(), Prj(), aBoardPath,
1249
1250 if( reporter.HasMessage() )
1251 {
1252 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1253 statusBar->AddWarningMessages( "load", reporter.GetMessages() );
1254 }
1255}
1256
1257
1259{
1261
1262 dlg.ShowModal();
1263
1264 return 0;
1265}
1266
1267
1269{
1271
1272 if( dlg.ShowModal() != wxID_OK )
1273 return 0;
1274
1275 // Refill zones if they are out-of-date so the export matches the current layout.
1276 m_toolMgr->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( m_frame );
1277
1279
1281 job.m_filename = m_frame->GetBoard()->GetFileName();
1283
1284 job.m_precision = dlg.GetPrecision();
1287
1288 WX_PROGRESS_REPORTER progressReporter( m_frame, _( "Generate ODB++ Files" ), 3, PR_CAN_ABORT );
1290
1291 DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( job, m_frame->GetBoard(), m_frame, &progressReporter, &reporter );
1292
1293 if( reporter.HasMessage() )
1294 DisplayError( m_frame, reporter.GetMessages() );
1295
1296 return 0;
1297}
const char * name
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
int GenerateODBPPFiles(const TOOL_EVENT &aEvent)
int New(const TOOL_EVENT &aEvent)
int Revert(const TOOL_EVENT &aEvent)
int GenIPC2581File(const TOOL_EVENT &aEvent)
int Open(const TOOL_EVENT &aEvent)
int OpenNonKicadBoard(const TOOL_EVENT &aEvent)
static std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition board.h:555
GAL_SET m_LegacyVisibleItems
Definition board.h:552
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1663
void BuildListOfNets()
Definition board.h:1170
void SetFileName(const wxString &aFileName)
Definition board.h:450
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition board.cpp:364
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3402
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:954
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition board.h:551
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:374
const wxString & GetFileName() const
Definition board.h:452
int GetFileFormatVersionAtLoad() const
Definition board.h:575
const wxString & GetGenerator() const
Adds an item to the container.
Definition board.h:633
void ClearProject()
Definition board.cpp:415
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1299
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:1183
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:3132
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1668
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:3446
bool m_LegacyCopperEdgeClearanceLoaded
Definition board.h:556
int GetCount() const
Return the number of objects in the list.
Definition collector.h:79
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
static void GenerateODBPPFiles(const JOB_EXPORT_PCB_ODB &aJob, BOARD *aBoard, PCB_EDIT_FRAME *aParentFrame=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, REPORTER *aErrorReporter=nullptr)
wxString GetOutputPath() const
wxString GetUnitsString() const
static std::vector< IMPORT_PROJECT_DESC > RunModal(wxWindow *aParent, const std::vector< IMPORT_PROJECT_DESC > &aProjectDesc)
Create and show a dialog (modal) and returns the data from it after completion.
static std::map< wxString, PCB_LAYER_ID > RunModal(wxWindow *aParent, const std::vector< INPUT_LAYER_DESC > &aLayerDesc)
Create and show a dialog (modal) and returns the data from it after completion.
int ShowModal() override
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void CheckForAutosaveFiles(const wxString &aProjectPath, const std::vector< wxString > &aExtensions)
Check for autosave files newer than their source files for the given project.
SETTINGS_MANAGER * GetSettingsManager() const
WX_INFOBAR * m_infoBar
wxTimer * m_autoSaveTimer
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxString GetMruPath() const
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
virtual void ClearFileHistory()
Remove all files from the file history.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
void SetMruPath(const wxString &aPath)
WX_INFOBAR * GetInfoBar()
std::unique_ptr< LOCKFILE > m_file_checker
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
void SetFocus() override
void SetModified()
Definition eda_item.cpp:260
bool IsModified() const
Definition eda_item.h:130
bool GetCreateNewProject() const
Gets the selected state of the copy subsheets option.
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
Definition collectors.h:38
An exception saying that the user cancelled an interactive part of a load, import,...
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()
virtual const wxString Problem() const
what was the problem?
ODB_COMPRESSION m_compressionMode
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
Definition job.cpp:157
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:38
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition kidialog.cpp:51
int ShowModal() override
Definition kidialog.cpp:89
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:451
Plugin class for import plugins that support remappable layers.
void SynchronizeTuningProfileProperties() const
Ensure time domain properties provider is synced with board / project settings if required.
bool RunRegisteredSaversAndCommit(const wxString &aProjectPath, const wxString &aTitle, const wxString &aTagFileType=wxEmptyString)
Run all registered savers and, if any staged changes differ from HEAD, create a commit.
void RemoveAutosaveFiles(const wxString &aProjectPath) const
Remove every autosave file under the project at aProjectPath regardless of which source it shadowed.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:309
Definition raii.h:34
static REPORTER & GetInstance()
Definition reporter.cpp:207
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:137
static TOOL_ACTION repairBoard
static TOOL_ACTION rehatchShapes
const VECTOR2I GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
virtual void UpdateStatusBar() override
Update the status bar information.
The main frame for Pcbnew.
void LoadDrawingSheet()
Load the drawing sheet file.
void ResolveDRCExclusions(bool aCreateMarkers)
If aCreateMarkers then create DRC exclusion markers from the serialized data.
void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
void OnModify() override
Must be called after a board change to set the modified flag.
bool CloseFootprintFieldsTableDialog()
void OnClearFileHistory(wxCommandEvent &aEvent)
bool SaveBoard(bool aSaveAs=false, bool aSaveCopy=false)
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
void ProjectChanged() override
Notification event that the project has changed.
void SaveProjectLocalSettings() override
Save changes to the project local settings.
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false, bool aHeadless=false)
Write the board data structures to aFileName.
bool IsContentModified() const override
Get if the current board has been modified but not saved.
bool LoadProjectSettings()
Load the current project's file configuration settings which are pertinent to this PCB_EDIT_FRAME ins...
bool Clear_Pcb(bool doAskAboutUnsavedChanges, bool aFinal=false)
Delete all and reinitialize the current board.
Definition initpcb.cpp:38
void OnBoardLoaded()
Update the state of the GUI after a new board is loaded or created.
void UpdateTitle()
Set the main window title bar text.
int inferLegacyEdgeClearance(BOARD *aBoard, bool aShowUserMsg=true)
const std::map< std::string, UTF8 > * m_importProperties
void reconcileImportedFootprintLibraries(std::vector< std::unique_ptr< FOOTPRINT > > aDefinitions, const wxString &aBoardPath)
Reconcile the footprint-library references of a freshly imported non-KiCad board so that every board ...
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Write the board data structures to a aFileName.
bool importFile(const wxString &aFileName, int aFileType, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void saveProjectSettings() override
Save any design-related project settings associated with this frame.
void OnFileHistory(wxCommandEvent &event)
static PLUGIN_REGISTRY * Instance()
Definition pcb_io_mgr.h:98
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
@ GEDA_PCB
Geda PCB file formats.
Definition pcb_io_mgr.h:66
@ ALTIUM_DESIGNER
Definition pcb_io_mgr.h:59
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition pcb_io_mgr.h:55
@ ALTIUM_CIRCUIT_MAKER
Definition pcb_io_mgr.h:57
@ ALTIUM_CIRCUIT_STUDIO
Definition pcb_io_mgr.h:58
@ CADSTAR_PCB_ARCHIVE
Definition pcb_io_mgr.h:60
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
static bool ImportGeneratesProjectLibrary(PCB_FILE_T aFileType)
Return true when importing aFileType should materialize a project footprint library.
A base class that BOARD loading and saving plugins should derive from.
Definition pcb_io.h:76
Collect all BOARD_ITEM objects on a given layer.
Definition collectors.h:545
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Test a BOARD_ITEM using this class's Inspector method, which does the collection.
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition collectors.h:551
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:892
A small class to help profiling.
Definition profile.h:46
double msecs(bool aSinceLast=false)
Definition profile.h:147
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
void AddPhases(int aNumPhases) override
bool KeepRefreshing(bool aWait=false) override
Update the UI dialog.
Plugin class for import plugins that support choosing a project.
LSET m_VisibleLayers
Board settings.
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
virtual void SetReadOnly(bool aReadOnly=true)
Definition project.h:161
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:177
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:207
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition project.cpp:201
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual bool HasMessage() const
Returns true if any messages were reported.
Definition reporter.h:143
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save a copy of the current project under the given path.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Call BackupProject() if a new backup is needed according to the current backup policy.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
TOOL_MANAGER * m_toolManager
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
Generic, UI-independent tool event.
Definition tool_event.h:167
static void ResolvePossibleSymlinks(wxFileName &aFilename)
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
A wrapper for reporting to a wxString object.
Definition reporter.h:242
const wxString & GetMessages() const
Definition reporter.cpp:188
Handle actions specific to filling copper zones.
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
Definition common.cpp:848
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
Definition confirm.cpp:38
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition confirm.cpp:274
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition confirm.cpp:146
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)
Declaration of the eda_3d_viewer class.
FOOTPRINT_IMPORT_RECONCILE_RESULT ReconcileImportedFootprints(std::vector< std::unique_ptr< FOOTPRINT > > aDefinitions, BOARD &aBoard, PROJECT &aProject, const wxString &aBoardPath, const std::map< std::string, UTF8 > *aProperties, REPORTER &aReporter)
Reconcile aBoard against the definitions an importer retained while loading it.
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition gestfich.cpp:343
#define WIN_STRING_DIR_SEP
Definition gestfich.h:39
#define UNIX_STRING_DIR_SEP
Definition gestfich.h:38
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string DesignRulesFileExtension
static const std::string KiCadPcbFileExtension
static wxString PcbFileWildcard()
bool ApplyImportedNetNameMap(BOARD &aBoard, const std::map< wxString, wxString > &aNames, REPORTER &aReporter)
Apply caller-selected imported net names without changing net identity or connectivity.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PROJECT & Prj()
Definition kicad.cpp:727
#define KICTL_CREATE
caller thinks requested project files may not exist.
#define KICTL_REVERT
reverting to a previously-saved (KiCad) file.
#define KICTL_IMPORT_LIB
import all footprints into a project library.
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
#define KICTL_NONKICAD_ONLY
chosen file is non-KiCad according to user
@ GAL_LAYER_ID_BITMASK_END
This is the end of the layers used for visibility bit masks in legacy board files.
Definition layer_ids.h:283
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ Edge_Cuts
Definition layer_ids.h:108
@ Rescue
Definition layer_ids.h:117
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
Definition layer_ids.h:383
File locking utilities.
This file contains miscellaneous commonly used macros and functions.
std::optional< std::map< wxString, wxString > > SplitNetNameMap(const wxString &aValue)
Decode a net-name map property value, or nothing when the value is not one.
constexpr char NET_NAME_MAP[]
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition unix/app.cpp:77
bool MakeWriteable(const wxString &aFilePath)
Ensures that a file has write permissions.
Definition unix/io.cpp:78
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:521
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
static const wxChar *const traceAllegroPerf
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
#define NAMELESS_PROJECT
default name for nameless projects
Definition project.h:41
KIWAY Kiway(KFCTL_STANDALONE)
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
bool show_import_issues
Stored value for "show import issues" when importing non-KiCad designs to this application.
std::function< void(PCB_IO &)> plugin_configurator
std::function< void(PCB_IO &)> post_load_hook
const std::map< std::string, UTF8 > * properties
PROGRESS_REPORTER * progress_reporter
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Container that describes file type info.
Definition io_base.h:43
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
Definition io_base.h:47
bool m_CanRead
Whether the IO can read this file type.
Definition io_base.h:52
virtual void PreloadLibraries(KIWAY *aKiway)
Definition kiway.h:290
std::string path
IbisParser parser & reporter
wxLogTrace helper definitions.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:80
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
Definition of file extensions used in Kicad.
#define PR_CAN_ABORT