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>
39#include <import_design_rules.h>
42#include <import_net_names.h>
43#include <kiface_base.h>
44#include <macros.h>
45#include <trace_helpers.h>
47#include <lockfile.h>
49#include <pcbnew_id.h>
51#include <tool/tool_manager.h>
52#include <board.h>
53#include <footprint.h>
54#include <collectors.h>
56#include <kiplatform/app.h>
57#include <kiplatform/ui.h>
59#include <widgets/wx_infobar.h>
62#include <paths.h>
63#include <pgm_base.h>
65#include <project_pcb.h>
69#include <pcb_io/pcb_io_mgr.h>
78#include <tools/pcb_actions.h>
81#include <board_commit.h>
82#include <reporter.h>
83#include <zone_filler.h>
85#include <widgets/kistatusbar.h>
87#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
88#include <kiplatform/io.h>
89
90#include <wx/stdpaths.h>
91#include <wx/ffile.h>
92#include <wx/file.h>
93#include <wx/filedlg.h>
94#include <wx/txtstrm.h>
95#include <wx/wfstream.h>
96#include <wx/zipstrm.h>
97#include <wx/dir.h>
98
100
101//#define USE_INSTRUMENTATION 1
102#define USE_INSTRUMENTATION 0
103
104static const wxChar* const traceAllegroPerf = wxT( "KICAD_ALLEGRO_PERF" );
105
106
115bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 )
116{
117 std::vector<IO_BASE::IO_FILE_DESC> descriptions;
118
119 for( const auto& plugin : PCB_IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins() )
120 {
121 bool isKiCad = plugin.m_type == PCB_IO_MGR::KICAD_SEXP || plugin.m_type == PCB_IO_MGR::LEGACY;
122
123 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
124 continue;
125
126 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
127 continue;
128
129 IO_RELEASER<PCB_IO> pi( plugin.m_createFunc() );
130 wxCHECK( pi, false );
131
132 const IO_BASE::IO_FILE_DESC& desc = pi->GetBoardFileDesc();
133
134 if( desc.m_FileExtensions.empty() || !desc.m_CanRead )
135 continue;
136
137 descriptions.emplace_back( desc );
138 }
139
140 wxString fileFiltersStr;
141 std::vector<std::string> allExtensions;
142 std::set<wxString> allWildcardsSet;
143
144 for( const IO_BASE::IO_FILE_DESC& desc : descriptions )
145 {
146 if( !fileFiltersStr.IsEmpty() )
147 fileFiltersStr += wxChar( '|' );
148
149 fileFiltersStr += desc.FileFilter();
150
151 for( const std::string& ext : desc.m_FileExtensions )
152 {
153 allExtensions.emplace_back( ext );
154 allWildcardsSet.insert( wxT( "*." ) + formatWildcardExt( ext ) + wxT( ";" ) );
155 }
156 }
157
158 wxString allWildcardsStr;
159
160 for( const wxString& wildcard : allWildcardsSet )
161 allWildcardsStr << wildcard;
162
163 if( aCtl & KICTL_KICAD_ONLY )
164 {
165 fileFiltersStr = _( "All KiCad Board Files" ) + AddFileExtListToFilter( allExtensions );
166 }
167 else
168 {
169 fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
170 + fileFiltersStr;
171 }
172
173 wxFileName fileName( *aFileName );
174 wxString path;
175 wxString name;
176
177 if( fileName.FileExists() )
178 {
179 path = fileName.GetPath();
180 name = fileName.GetFullName();
181 }
182 else
183 {
184 path = aParent->GetMruPath();
185
186 if( path.IsEmpty() )
188 // leave name empty
189 }
190
191 bool kicadFormat = ( aCtl & KICTL_KICAD_ONLY );
192
193 wxFileDialog dlg( aParent, kicadFormat ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
194 path, name, fileFiltersStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
195
196 FILEDLG_IMPORT_NON_KICAD importOptions( aParent->config()->m_System.show_import_issues );
197
198 if( !kicadFormat )
199 dlg.SetCustomizeHook( importOptions );
200
202
203 if( dlg.ShowModal() == wxID_OK )
204 {
205 *aFileName = dlg.GetPath();
206 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
207
208 if( !kicadFormat )
209 aParent->config()->m_System.show_import_issues = importOptions.GetShowIssues();
210
211 return true;
212 }
213 else
214 {
215 return false;
216 }
217}
218
219
229bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
230{
231 wxString wildcard = FILEEXT::PcbFileWildcard();
232 wxFileName fn = *aFileName;
233
235
236 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
237 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
238
239// Add a "Create a project" checkbox in standalone mode and one isn't loaded
240 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
241
242 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
243 dlg.SetCustomizeHook( newProjectHook );
244
246
247 if( dlg.ShowModal() != wxID_OK )
248 return false;
249
250 *aFileName = dlg.GetPath();
251 *aFileName = EnsureFileExtension( *aFileName, FILEEXT::KiCadPcbFileExtension );
252
253 if( newProjectHook.IsAttachedToDialog() )
254 *aCreateProject = newProjectHook.GetCreateNewProject();
255 else if( !aParent->Prj().IsNullProject() )
256 *aCreateProject = true;
257
258 return true;
259}
260
261
262void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
263{
264 wxString filename = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
265
266 if( !filename.IsEmpty() )
267 {
268 if( !wxFileName::IsFileReadable( filename ) )
269 {
270 if( !AskLoadBoardFileName( this, &filename, KICTL_KICAD_ONLY ) )
271 return;
272 }
273
274 OpenProjectFiles( std::vector<wxString>( 1, filename ), KICTL_KICAD_ONLY );
275 }
276}
277
278
279void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
280{
282}
283
284
286{
287 // Only standalone mode can directly load a new document
288 if( !Kiface().IsSingle() )
289 return false;
290
291 int open_ctl = KICTL_KICAD_ONLY;
292 wxString fileName = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
293
294 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
295 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
296
297 return 0;
298}
299
300
302{
303 // Note: we explicitly allow this even if not in standalone mode for now, even though it is dangerous.
304 int open_ctl = KICTL_NONKICAD_ONLY;
305 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
306
307 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
308 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
309
310 return 0;
311}
312
313
315{
316 wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
317
318 if( !IsOK( m_frame, wxString::Format( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() ) ) )
319 return false;
320
321 return m_frame->ReloadFromDisk();
322}
323
324
326{
327 // Only standalone mode can directly load a new document
328 if( !Kiface().IsSingle() )
329 return false;
330
331 if( !m_frame->CloseFootprintFieldsTableDialog() )
332 return false;
333
334 if( m_frame->IsContentModified() )
335 {
336 wxFileName fileName = m_frame->GetBoard()->GetFileName();
337 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
338 "continuing?" );
339
340 if( !HandleUnsavedChanges( m_frame, wxString::Format( saveMsg, fileName.GetFullName() ),
341 [&]()->bool
342 {
343 return m_frame->SaveBoard();
344 } ) )
345 {
346 return false;
347 }
348 }
349 else if( !m_frame->GetBoard()->IsEmpty() )
350 {
351 if( !IsOK( m_frame, _( "Current Board will be closed. Continue?" ) ) )
352 return false;
353 }
354
355 m_frame->SaveProjectLocalSettings();
356
357 m_frame->GetBoard()->ClearProject();
358 m_frame->GetSettingsManager()->UnloadProject( &m_frame->Prj() );
359
360 if( !m_frame->Clear_Pcb( false ) )
361 return false;
362
363 m_frame->LoadProjectSettings();
364 m_frame->LoadDrawingSheet();
365
366 m_frame->OnBoardLoaded();
367 m_frame->OnModify();
368
369 return 0;
370}
371
372
373bool PCB_EDIT_FRAME::SaveBoard( bool aSaveAs, bool aSaveCopy )
374{
375 if( !aSaveAs )
376 {
377 if( !GetBoard()->GetFileName().IsEmpty() )
378 {
379 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
380 {
381 m_autoSaveRequired = false;
382 return true;
383 }
384
385 return false;
386 }
387 }
388
389 wxString orig_name;
390
391 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
392
393 if( orig_name.IsEmpty() )
394 orig_name = NAMELESS_PROJECT;
395
396 wxFileName savePath( Prj().GetProjectFullName() );
397
398 if( !savePath.IsOk() || !savePath.IsDirWritable() )
399 {
400 savePath = GetMruPath();
401
402 if( !savePath.IsOk() || !savePath.IsDirWritable() )
404 }
405
406 wxFileName fn( savePath.GetPath(), orig_name, FILEEXT::KiCadPcbFileExtension );
407 wxString filename = fn.GetFullPath();
408 bool createProject = false;
409 bool success = false;
410
411 if( AskSaveBoardFileName( this, &filename, &createProject ) )
412 {
413 if( aSaveCopy )
414 {
415 success = SavePcbCopy( EnsureFileExtension( filename, FILEEXT::KiCadPcbFileExtension ), createProject );
416 }
417 else
418 {
419 success = SavePcbFile( filename, aSaveAs, createProject );
420
421 if( success )
422 m_autoSaveRequired = false;
423 }
424 }
425
426 return success;
427}
428
429
430int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard, bool aShowUserMsg )
431{
432 PCB_LAYER_COLLECTOR collector;
433
434 collector.SetLayerId( Edge_Cuts );
435 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
436
437 int edgeWidth = -1;
438 bool mixed = false;
439
440 for( int i = 0; i < collector.GetCount(); i++ )
441 {
442 if( collector[i]->Type() == PCB_SHAPE_T )
443 {
444 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
445
446 if( edgeWidth != -1 && edgeWidth != itemWidth )
447 {
448 mixed = true;
449 edgeWidth = std::max( edgeWidth, itemWidth );
450 }
451 else
452 {
453 edgeWidth = itemWidth;
454 }
455 }
456 }
457
458 if( mixed && aShowUserMsg )
459 {
460 // If they had different widths then we can't ensure that fills will be the same.
461 DisplayInfoMessage( this,
462 _( "If the zones on this board are refilled the Copper Edge "
463 "Clearance setting will be used (see Board Setup > Design "
464 "Rules > Constraints).\n This may result in different fills "
465 "from previous KiCad versions which used the line thicknesses "
466 "of the board boundary on the Edge Cuts layer." ) );
467 }
468
469 return std::max( 0, edgeWidth / 2 );
470}
471
472
474{
475 wxString fileName = GetBoard()->GetFileName();
476
477 if( fileName.IsEmpty() )
478 return false;
479
480 fileName = Prj().AbsolutePath( fileName );
481
482 // The caller already handled confirmation, so skip the save prompt.
483 GetScreen()->SetContentModified( false );
484 ReleaseFile();
485 return OpenProjectFiles( std::vector<wxString>( 1, fileName ), KICTL_REVERT );
486}
487
488
489bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
490{
491 // This is for python:
492 if( aFileSet.size() != 1 )
493 {
494 DisplayError( this, wxString::Format( "Pcbnew:%s() takes a single filename", __func__ ) );
495 return false;
496 }
497
498 wxString fullFileName( aFileSet[0] );
499 wxFileName wx_filename( fullFileName );
500 wxString msg;
501
502 if( Kiface().IsSingle() )
504
505 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
506 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
507
508 std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
509
510 if( !lock->Valid() )
511 {
512 // If project-level lock override was already granted, silently override this file's lock
513 if( Prj().IsLockOverrideGranted() )
514 {
515 lock->OverrideLock();
516 }
517 else
518 {
519 msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ),
520 wx_filename.GetFullName(),
521 lock->GetUsername(),
522 lock->GetHostname() );
523
524 if( !AskOverrideLock( this, msg ) )
525 return false;
526
527 lock->OverrideLock();
528 }
529 }
530
532 return false;
533
534 if( IsContentModified() )
535 {
536 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
537 [&]() -> bool
538 {
539 return SavePcbFile( GetBoard()->GetFileName() );
540 } ) )
541 {
542 return false;
543 }
544 }
545
546 wxFileName pro = fullFileName;
547 pro.SetExt( FILEEXT::ProjectFileExtension );
548
549 bool is_new = !wxFileName::IsFileReadable( fullFileName );
550
551 wxString previousBoardFileName = GetBoard() ? GetBoard()->GetFileName() : wxString();
552
553 // If its a non-existent PCB and caller thinks it exists
554 if( is_new && !( aCtl & KICTL_CREATE ) )
555 {
556 // notify user that fullFileName does not exist, ask if user wants to create it.
557 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
558
559 if( !IsOK( this, msg ) )
560 return false;
561 }
562
563 // Get rid of any existing warnings about the old board
564 GetInfoBar()->Dismiss();
565 m_loadNoticeInfoBar->Dismiss();
566
567 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
568 statusBar->ClearWarningMessages( "load" );
569
570 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Create PCB" ) : _( "Load PCB" ), 1,
571 PR_CAN_ABORT );
572 WX_STRING_REPORTER loadReporter;
573 LOAD_INFO_REPORTER_SCOPE loadReporterScope( &loadReporter );
574
575 // No save prompt (we already prompted above), and only reset to a new blank board if new
576 Clear_Pcb( false, !is_new );
577
579
580 if( !is_new )
581 pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
582
583 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
584 {
585 progressReporter.Hide();
586 DisplayErrorMessage( this, _( "File format is not supported" ), wxEmptyString );
587 return false;
588 }
589
590 bool converted = pluginType != PCB_IO_MGR::LEGACY && pluginType != PCB_IO_MGR::KICAD_SEXP;
591
592 // Loading a project should only be done under carefully considered circumstances.
593
594 // The calling code should know not to ask me here to change projects unless
595 // it knows what consequences that will have on other KIFACEs running and using
596 // this same PROJECT. It can be very harmful if that calling code is stupid.
598 bool setProject;
599
600 if( Kiface().IsSingle() || !( aCtl & KICTL_NONKICAD_ONLY ) )
601 setProject = pro.GetFullPath() != mgr->Prj().GetProjectFullName();
602 else
603 setProject = Prj().GetProjectFullName().IsEmpty();
604
605 if( setProject )
606 {
607 // calls SaveProject
609
611 mgr->UnloadProject( &mgr->Prj() );
612
613 mgr->LoadProject( pro.GetFullPath() );
614
615 if( Kiface().IsSingle() )
616 {
617 // Standalone opens can switch to a different project. Preload libraries after the
618 // project switch so the board load sees project-local library tables.
621 }
622
623 // Do not allow saving a project if one doesn't exist. This normally happens if we are
624 // opening a board that has been moved from its project folder.
625 // For converted projects, we don't want to set the read-only flag because we want a
626 // project to be saved for the new file in case things like netclasses got migrated.
627 Prj().SetReadOnly( !pro.Exists() && !converted );
628 }
629
630 // Crash-recovery: when zip-format autosave is active, look for autosave files newer than
631 // the saved board and offer to recover them before the load happens.
632 if( !is_new )
633 CheckForAutosaveFiles( wx_filename.GetPath(), { FILEEXT::KiCadPcbFileExtension } );
634
635 // custom rules the importer derived, saved with the board once its name is known
636 wxString importedRules;
637
638 if( is_new )
639 {
640 // Link the existing blank board to the new project
641 GetBoard()->SetProject( &Prj() );
642
643 GetBoard()->SetFileName( fullFileName );
644
645 OnModify();
646 }
647 else
648 {
649 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
650 bool failedLoad = false;
651
652 // importer template footprints, captured at load for reconciliation
653 std::vector<std::unique_ptr<FOOTPRINT>> importedLibFootprints;
654
655 try
656 {
657 std::map<std::string, UTF8> props;
658
660 props.insert( m_importProperties->begin(), m_importProperties->end() );
661
662 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
663 props["page_width"] = std::to_string( GetPageSizeIU().x );
664 props["page_height"] = std::to_string( GetPageSizeIU().y );
665
666#if USE_INSTRUMENTATION
667 // measure the time to load a BOARD.
668 int64_t startTime = GetRunningMicroSecs();
669#endif
670 BOARD_LOADER::OPTIONS loaderOptions;
671 loaderOptions.properties = &props;
672 loaderOptions.progress_reporter = &progressReporter;
673 loaderOptions.reporter = config()->m_System.show_import_issues
674 ? static_cast<REPORTER*>( &loadReporter )
675 : static_cast<REPORTER*>( &NULL_REPORTER::GetInstance() );
676 loaderOptions.initialize_after_load = false;
677
678 loaderOptions.post_load_hook =
679 [&]( PCB_IO& aPlugin )
680 {
681 importedRules = aPlugin.GetImportedDesignRules();
682
683 if( !( aCtl & KICTL_IMPORT_LIB ) )
684 return;
685
686 try
687 {
688 for( FOOTPRINT* fp : aPlugin.GetImportedCachedLibraryFootprints() )
689 importedLibFootprints.emplace_back( fp );
690 }
691 catch( const IO_ERROR& )
692 {
693 // no cached library, reconcile from placed only
694 }
695 };
696
697 loaderOptions.plugin_configurator =
698 [&]( PCB_IO& aPlugin )
699 {
700 if( LAYER_MAPPABLE_PLUGIN* mappable_pi =
701 dynamic_cast<LAYER_MAPPABLE_PLUGIN*>( &aPlugin ) )
702 {
703 if( !ADVANCED_CFG::GetCfg().m_ImportSkipLayerMapping )
704 {
705 const auto layerMapCallback =
706 [this]( const std::vector<INPUT_LAYER_DESC>& aLayers )
707 {
708 return DIALOG_MAP_LAYERS::RunModal( this, aLayers );
709 };
710
711 mappable_pi->RegisterCallback( layerMapCallback );
712 }
713 }
714
715 if( PROJECT_CHOOSER_PLUGIN* chooser_pi =
716 dynamic_cast<PROJECT_CHOOSER_PLUGIN*>( &aPlugin ) )
717 {
718 const auto chooseProjectCallback =
719 [this]( const std::vector<IMPORT_PROJECT_DESC>& aProjects )
720 {
721 return DIALOG_IMPORT_CHOOSE_PROJECT::RunModal( this, aProjects );
722 };
723
724 chooser_pi->RegisterCallback( chooseProjectCallback );
725 }
726
727 aPlugin.SetQueryUserCallback(
728 [&]( wxString aTitle, int aIcon, wxString aMessage,
729 wxString aAction ) -> bool
730 {
731 KIDIALOG dlg( nullptr, aMessage, aTitle,
732 wxOK | wxCANCEL | aIcon );
733
734 if( !aAction.IsEmpty() )
735 dlg.SetOKLabel( aAction );
736
737 dlg.DoNotShowCheckbox( aMessage, 0 );
738
739 return dlg.ShowModal() == wxID_OK;
740 } );
741 };
742
743 std::unique_ptr<BOARD> loaded =
744 BOARD_LOADER::Load( fullFileName, pluginType, &Prj(), loaderOptions );
745
746 if( loaded && props.count( IMPORT_PROJ_PROPS::NET_NAME_MAP ) )
747 {
748 std::optional<std::map<wxString, wxString>> netNames =
750 props.at( IMPORT_PROJ_PROPS::NET_NAME_MAP ).wx_str() );
751
752 if( !netNames )
753 THROW_IO_ERROR( _( "Invalid imported net-name map." ) );
754
755 if( !ApplyImportedNetNameMap( *loaded, *netNames, loadReporter ) )
756 THROW_IO_ERROR( _( "Cannot apply imported net-name map to the board." ) );
757 }
758
759 loadedBoard = loaded.release();
760
761#if USE_INSTRUMENTATION
762 int64_t stopTime = GetRunningMicroSecs();
763 printf( "PCB_IO::Load(): %u usecs\n", stopTime - startTime );
764#endif
765 }
766 catch( const FUTURE_FORMAT_ERROR& ffe )
767 {
768 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
769 progressReporter.Hide();
770 DisplayErrorMessage( this, msg, ffe.Problem() );
771
772 failedLoad = true;
773 }
774 catch( const IO_CANCELLED& )
775 {
776 // A user-cancelled load is not an error; abandon it without a dialog.
777 failedLoad = true;
778 }
779 catch( const IO_ERROR& ioe )
780 {
781 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
782 progressReporter.Hide();
783 DisplayErrorMessage( this, msg, ioe.What() );
784
785 failedLoad = true;
786 }
787 catch( const std::bad_alloc& )
788 {
789 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
790 progressReporter.Hide();
791 DisplayErrorMessage( this, msg, wxEmptyString );
792
793 failedLoad = true;
794 }
795
796 if( failedLoad || !loadedBoard )
797 {
798 // We didn't create a new blank board above, so do that now
799 Clear_Pcb( false );
800
801 // Show any messages collected before the failure
802 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
803 statusBar->AddWarningMessages( "load", loadReporter.GetMessages() );
804
805 return false;
806 }
807
808 if( converted && GetPcbNewSettings()->m_ImportKeepKiCadLayerNames )
809 {
810 for( PCB_LAYER_ID layer : loadedBoard->GetEnabledLayers().Seq() )
811 loadedBoard->SetLayerName( layer, wxEmptyString );
812 }
813
814 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
815 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
816 // compiled.
817 Raise();
818
819 // Skip (possibly expensive) connectivity build here; we build it below after load
820 progressReporter.AddPhases( 1 );
821 progressReporter.AdvancePhase( _( "Finalizing board" ) );
822 progressReporter.KeepRefreshing();
823
824 PROF_TIMER postLoadTimer;
825 SetBoard( loadedBoard, false, &progressReporter );
826 wxLogTrace( traceAllegroPerf, wxT( "Post-load SetBoard: %.3f ms" ),
827 postLoadTimer.msecs( true ) );
828
829 if( loadedBoard->m_LegacyDesignSettingsLoaded )
830 {
831 Prj().SetReadOnly( false );
832
833 // Before we had a copper edge clearance setting, the edge line widths could be used
834 // as a kludge to control them. So if there's no setting then infer it from the
835 // edge widths.
836 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
837 {
838 // Do not show the inferred edge clearance warning dialog when loading third
839 // party boards. For some reason the dialog completely hangs all of KiCad and
840 // the imported board cannot be saved.
841 int edgeClearance = inferLegacyEdgeClearance( loadedBoard, !converted );
842 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
843 }
844
845 // On save; design settings will be removed from the board
846 loadedBoard->SetModified();
847 }
848
849 // Move legacy view settings to local project settings
850 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
851 {
853 loadedBoard->SetModified();
854 }
855
857 {
859 loadedBoard->SetModified();
860 }
861
862 if( !loadedBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
863 {
864 m_infoBar->RemoveAllButtons();
865 m_infoBar->AddCloseButton();
866 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
867 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
868 }
869
870 // we should not ask PCB_IOs to do these items:
871 loadedBoard->BuildListOfNets();
872 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildListOfNets: %.3f ms" ),
873 postLoadTimer.msecs( true ) );
874
875 progressReporter.KeepRefreshing();
876
877 m_toolManager->RunAction( PCB_ACTIONS::repairBoard, true);
878 wxLogTrace( traceAllegroPerf, wxT( "Post-load repairBoard: %.3f ms" ),
879 postLoadTimer.msecs( true ) );
880
881 progressReporter.KeepRefreshing();
882
884 wxLogTrace( traceAllegroPerf, wxT( "Post-load rehatchShapes: %.3f ms" ),
885 postLoadTimer.msecs( true ) );
886
887 progressReporter.KeepRefreshing();
888
889 if( loadedBoard->IsModified() )
890 OnModify();
891 else
892 GetScreen()->SetContentModified( false );
893
894 if( ( pluginType == PCB_IO_MGR::LEGACY )
895 || ( pluginType == PCB_IO_MGR::KICAD_SEXP
897 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
898 {
899 m_infoBar->RemoveAllButtons();
900 m_infoBar->AddCloseButton();
901 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
902 "It will be converted to the new format when saved." ),
903 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
904 }
905
906 // extract a project fp library and re-link board FPIDs so update-from-schematic works
907 if( aCtl & KICTL_IMPORT_LIB )
908 reconcileImportedFootprintLibraries( std::move( importedLibFootprints ), fullFileName );
909 }
910
911 {
912 wxString fname;
913
914 if( !previousBoardFileName.IsEmpty() && ( aCtl & KICTL_NONKICAD_ONLY ) && !setProject )
915 {
916 fname = previousBoardFileName;
917 }
918 else
919 {
920 wxFileName fn;
921
922 fn.SetPath( Prj().GetProjectPath() );
923 fn.SetName( Prj().GetProjectName() );
925
926 fname = fn.GetFullPath();
927
928 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
929 }
930
931 GetBoard()->SetFileName( fname );
932 }
933
934 SaveImportedDesignRules( importedRules, wxFileName( GetBoard()->GetDesignRulesPath() ), loadReporter );
935
936 // Lock the file newly opened:
937 m_file_checker.reset( lock.release() );
938
939 if( !converted )
940 UpdateFileHistory( GetBoard()->GetFileName() );
941
942 std::vector<ZONE*> toFill;
943
944 // Rebuild list of nets (full ratsnest rebuild)
945 PROF_TIMER connectivityTimer;
946 GetBoard()->BuildConnectivity( &progressReporter );
947 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildConnectivity: %.3f ms" ),
948 connectivityTimer.msecs( true ) );
949
950 // Load project settings after setting up board; some of them depend on the nets list
953 wxLogTrace( traceAllegroPerf, wxT( "Post-load LoadProjectSettings+DrawingSheet: %.3f ms" ),
954 connectivityTimer.msecs( true ) );
955
956 // Resolve DRC exclusions after project settings are loaded
957 ResolveDRCExclusions( true );
958
959 // Initialise caches used by component classes
961
962 // Initialise time domain tuning caches
964 wxLogTrace( traceAllegroPerf, wxT( "Post-load DRC+ComponentClass+Tuning caches: %.3f ms" ),
965 connectivityTimer.msecs( true ) );
966
967 // Syncs the UI (appearance panel, etc) with the loaded board and project
969 wxLogTrace( traceAllegroPerf, wxT( "Post-load OnBoardLoaded: %.3f ms" ),
970 connectivityTimer.msecs( true ) );
971 wxLogTrace( traceAllegroPerf, wxT( "=== Post-load pipeline total: %.3f ms ===" ),
972 connectivityTimer.msecs() );
973
974 // Refresh the 3D view, if any
975 if( EDA_3D_VIEWER_FRAME* our3DViewer = GetOur3DViewerFrame() )
976 our3DViewer->NewDisplay();
977
978#if 0 && defined(DEBUG)
979 // Output the board object tree to stdout, but please run from command prompt:
980 GetBoard()->Show( 0, std::cout );
981#endif
982
983 // from EDA_APPL which was first loaded BOARD only:
984 {
985 /* For an obscure reason the focus is lost after loading a board file
986 * when starting up the process.
987 * (seems due to the recreation of the layer manager after loading the file)
988 * Give focus to main window and Drawpanel
989 * must be done for these 2 windows (for an obscure reason ...)
990 * Linux specific
991 * This is more a workaround than a fix.
992 */
993 SetFocus();
994 GetCanvas()->SetFocus();
995 }
996
997 if( !setProject )
998 {
999 // If we didn't reload the project, we still need to call ProjectChanged() to ensure
1000 // frame-specific initialization happens (like registering the autosave saver).
1001 // When running under the project manager, KIWAY::ProjectChanged() was called before
1002 // this frame existed, so we need to call our own ProjectChanged() now.
1004 }
1005
1006 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1007 statusBar->AddWarningMessages( "load", loadReporter.GetMessages() );
1008
1009 // A standalone editor has no project manager to attach the git session for it.
1011
1012 return true;
1013}
1014
1015
1016bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
1017 bool aChangeProject )
1018{
1019 // please, keep it simple. prompting goes elsewhere.
1020 wxFileName pcbFileName = aFileName;
1021
1022 if( pcbFileName.GetExt() == FILEEXT::LegacyPcbFileExtension )
1023 pcbFileName.SetExt( FILEEXT::KiCadPcbFileExtension );
1024
1025 // Write through symlinks, don't replace them
1027
1028 if( !IsWritable( pcbFileName ) )
1029 {
1030 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1031 pcbFileName.GetFullPath() );
1032
1033 DisplayError( this, msg );
1034 return false;
1035 }
1036
1037 // TODO: these will break if we ever go multi-board
1038 wxFileName projectFile( pcbFileName );
1039 wxFileName rulesFile( pcbFileName );
1040 wxString msg;
1041
1042 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1043 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1044
1045 if( projectFile.FileExists() )
1046 {
1048 }
1049 else if( aChangeProject )
1050 {
1051 Prj().SetReadOnly( false );
1052 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1053 }
1054
1055 wxFileName currentRules( GetBoard()->GetDesignRulesPath() );
1056
1057 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1058 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1059
1060 if( !msg.IsEmpty() )
1061 {
1062 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1063 rulesFile.GetFullPath() ) );
1064 }
1065
1066 if( projectFile.FileExists() )
1067 {
1068 // Save various DRC parameters, such as violation severities (which may have been
1069 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1071
1074 }
1075
1076 wxString lowerTxt;
1077
1078 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1079 // hidden or read-only. This can happen when files are synced via cloud services.
1080 if( pcbFileName.FileExists() )
1081 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1082
1083 try
1084 {
1086
1087 pi->SaveBoard( pcbFileName.GetFullPath(), *GetBoard(), nullptr );
1088 }
1089 catch( const IO_ERROR& ioe )
1090 {
1091 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1092 pcbFileName.GetFullPath(),
1093 ioe.What() ) );
1094 return false;
1095 }
1096
1097 WX_STRING_REPORTER backupReporter;
1098
1099 if( !Kiface().IsSingle() )
1100 GetSettingsManager()->TriggerBackupIfNeeded( backupReporter );
1101
1102 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1103
1104 // Update the lock in case it was a Save As
1105 LockFile( pcbFileName.GetFullPath() );
1106
1107 // Put the saved file in File History if requested
1108 if( addToHistory )
1109 UpdateFileHistory( GetBoard()->GetFileName() );
1110
1111 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1112
1113 SetStatusText( lowerTxt, 0 );
1114
1115 // Get rid of the old version conversion warning, or any other dismissable warning :)
1116 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1117 m_infoBar->Dismiss();
1118
1119 if( m_infoBar->IsShownOnScreen() && m_infoBar->HasCloseButton() )
1120 m_infoBar->Dismiss();
1121
1122 if( backupReporter.HasMessage() )
1123 {
1124 wxString backupMsg = backupReporter.GetMessages();
1125 m_infoBar->ShowMessageFor( backupMsg.Trim(), 10000, wxICON_WARNING );
1126 }
1127
1128 GetScreen()->SetContentModified( false );
1129 UpdateTitle();
1131
1132 // Capture entire project state for PCB save events. Skip when running standalone
1133 // without a project loaded - the save path can land anywhere on the filesystem and
1134 // there is no project context for a snapshot to live under.
1135 if( !Prj().IsNullProject() )
1136 {
1137 Kiway().LocalHistory().RunRegisteredSaversAndCommit( Prj().GetProjectPath(), wxS( "PCB Save" ), wxS( "pcb" ) );
1138
1139 // Drop the autosave file for the board we just persisted. Scope to the PCB
1140 // source so a concurrent open eeschema does not lose recovery data for an
1141 // unsaved schematic sheet. RunRegisteredSaversAndCommit above is a no-op when
1142 // format is ZIP; this call is conversely a no-op in INCREMENTAL mode.
1143 Kiway().LocalHistory().RemoveAutosaveFiles( Prj().GetProjectPath(), { pcbFileName.GetFullPath() } );
1144 }
1145
1146 if( m_autoSaveTimer )
1147 m_autoSaveTimer->Stop();
1148
1149 m_autoSavePending = false;
1150 m_autoSaveRequired = false;
1151
1153
1154 return true;
1155}
1156
1157
1158bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
1159{
1160 wxFileName pcbFileName( aFileName );
1161
1162 if( !IsWritable( pcbFileName ) )
1163 {
1164 if( !aHeadless )
1165 {
1166 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1167 pcbFileName.GetFullPath() ) );
1168 }
1169 return false;
1170 }
1171
1172 // Save various DRC parameters, such as violation severities (which may have been
1173 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1175
1178
1179 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1180 // hidden or read-only. This can happen when files are synced via cloud services.
1181 if( pcbFileName.FileExists() )
1182 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1183
1184 try
1185 {
1187
1188 wxASSERT( pcbFileName.IsAbsolute() );
1189
1190 pi->SaveBoard( pcbFileName.GetFullPath(), *GetBoard(), nullptr );
1191 }
1192 catch( const IO_ERROR& ioe )
1193 {
1194 if( !aHeadless )
1195 {
1196 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1197 pcbFileName.GetFullPath(),
1198 ioe.What() ) );
1199 }
1200
1201 return false;
1202 }
1203
1204 wxFileName projectFile( pcbFileName );
1205 wxFileName rulesFile( pcbFileName );
1206 wxString msg;
1207
1208 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1209 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1210
1211 if( aCreateProject && !projectFile.FileExists() )
1212 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1213
1214 wxFileName currentRules( GetBoard()->GetDesignRulesPath() );
1215
1216 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1217 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1218
1219 if( !msg.IsEmpty() && !aHeadless )
1220 {
1221 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1222 rulesFile.GetFullPath() ) );
1223 }
1224
1225 return true;
1226}
1227
1228
1229bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
1230 const std::map<std::string, UTF8>* aProperties )
1231{
1232 NULLER raiiNuller( (void*&) m_importProperties );
1233
1234 m_importProperties = aProperties;
1235
1237
1238 switch( fileType )
1239 {
1241 case PCB_IO_MGR::EAGLE:
1251 case PCB_IO_MGR::PADS:
1253 {
1254 int ctl = KICTL_NONKICAD_ONLY;
1255
1257 ctl |= KICTL_IMPORT_LIB;
1258
1259 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), ctl );
1260 }
1261
1262 default:
1263 return false;
1264 }
1265}
1266
1267
1269 std::vector<std::unique_ptr<FOOTPRINT>> aDefinitions, const wxString& aBoardPath )
1270{
1272
1273 ReconcileImportedFootprints( std::move( aDefinitions ), *GetBoard(), Prj(), aBoardPath,
1275
1276 if( reporter.HasMessage() )
1277 {
1278 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1279 statusBar->AddWarningMessages( "load", reporter.GetMessages() );
1280 }
1281}
1282
1283
1285{
1287
1288 dlg.ShowModal();
1289
1290 return 0;
1291}
1292
1293
1295{
1297 dlg.ShowModal();
1298
1299 return 0;
1300}
const char * name
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:411
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition board.h:565
GAL_SET m_LegacyVisibleItems
Definition board.h:562
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1679
void BuildListOfNets()
Definition board.h:1180
void SetFileName(const wxString &aFileName)
Definition board.h:452
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:369
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3221
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:950
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition board.h:561
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:379
const wxString & GetFileName() const
Definition board.h:454
int GetFileFormatVersionAtLoad() const
Definition board.h:585
const wxString & GetGenerator() const
Definition board.h:643
void ClearProject()
Definition board.cpp:420
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:1174
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:2949
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1684
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:3265
bool m_LegacyCopperEdgeClearanceLoaded
Definition board.h:566
BOARD_DESIGN_SETTINGS & GetDesignSettings()
Definition board.cpp:1290
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 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.
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()
void ReleaseFile()
Release the current file marked in use.
std::unique_ptr< LOCKFILE > m_file_checker
Prevents opening same file multiple times.
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
void RefreshGitCommitPane()
Attach the git session if needed and refresh the version-control pane, when it is shown.
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 create new project option.
bool IsAttachedToDialog() const
Gets if this hook has attached controls to a dialog box.
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?
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:457
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 * GetOur3DViewerFrame()
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()
bool ReloadFromDisk()
Reload the board from disk.
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.
WX_INFOBAR * m_loadNoticeInfoBar
Secondary infobar that stacks above the main one; reserved for load-time notices (currently the WRL -...
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:100
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
@ TARGET3001
TARGET 3001! project.
Definition pcb_io_mgr.h:77
@ 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 PCB_IO 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:78
Collect all BOARD_ITEM objects on a given layer.
Definition collectors.h:546
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:552
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
Definition pgm_base.cpp:908
A small class to help profiling.
Definition profile.h:46
double msecs(bool aSinceLast=false)
Definition profile.h:148
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:270
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:207
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition project.cpp:500
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition project.cpp:294
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
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
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:880
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.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition cvpcb.cpp:165
#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:361
#define WIN_STRING_DIR_SEP
Definition gestfich.h:41
#define UNIX_STRING_DIR_SEP
Definition gestfich.h:40
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string DesignRulesFileExtension
static const std::string KiCadPcbFileExtension
static wxString PcbFileWildcard()
bool SaveImportedDesignRules(const wxString &aRules, const wxFileName &aBoardPath, REPORTER &aReporter)
Save the custom rules an importer derived beside the board it produced.
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
PROJECT & Prj()
Definition kicad.cpp:737
#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:389
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:83
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:640
#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:40
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:298
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