KiCad PCB EDA Suite
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) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <confirm.h>
27#include <core/arraydim.h>
28#include <gestfich.h>
29#include <pcb_edit_frame.h>
32#include <widgets/msgpanel.h>
33#include <fp_lib_table.h>
34#include <kiface_base.h>
35#include <macros.h>
36#include <trace_helpers.h>
37#include <lockfile.h>
38#include <wx/snglinst.h>
40#include <pcbnew_id.h>
41#include <io_mgr.h>
43#include <tool/tool_manager.h>
44#include <board.h>
45#include <wx/checkbox.h>
46#include <wx/stdpaths.h>
48#include <kiplatform/app.h>
50#include <widgets/wx_infobar.h>
53#include <paths.h>
60#include <tools/pcb_actions.h>
61#include "footprint_info_impl.h"
62#include "board_commit.h"
63#include "zone_filler.h"
64#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
65
66#include <wx/wupdlock.h>
67#include <wx/filedlg.h>
68#include <wx/wfstream.h>
69#include <wx/txtstrm.h>
70
71#if wxCHECK_VERSION( 3, 1, 7 )
72#include "widgets/filedlg_hook_save_project.h"
73#else
74#include "widgets/legacyfiledlg_save_project.h"
75#endif
76
77//#define USE_INSTRUMENTATION 1
78#define USE_INSTRUMENTATION 0
79
80
90bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, int* aCtl, wxString* aFileName,
91 bool aKicadFilesOnly )
92{
93 // This is a subset of all PLUGINs which are trusted to be able to
94 // load a BOARD. User may occasionally use the wrong plugin to load a
95 // *.brd file (since both legacy and eagle use *.brd extension),
96 // but eventually *.kicad_pcb will be more common than legacy *.brd files.
97
98 // clang-format off
99 static const struct
100 {
101 const wxString& filter;
102 IO_MGR::PCB_FILE_T pluginType;
103 } loaders[] =
104 {
105 // Current Kicad board files.
107
108 // Old Kicad board files.
110
111 // Import Altium Circuit Maker board files.
113
114 // Import Altium Circuit Studio board files.
116
117 // Import Altium Designer board files.
119
120 // Import Cadstar PCB Archive board files.
122
123 // Import Eagle board files.
125
126 // Import PCAD board files.
128
129 // Import Fabmaster board files.
131 };
132 // clang-format on
133
134 wxFileName fileName( *aFileName );
135 wxString fileFilters;
136
137 if( aKicadFilesOnly )
138 {
139 std::vector<std::string> fileExtensions;
140
141 for( unsigned ii = 0; ii < 2; ++ii )
142 {
143 if( !fileFilters.IsEmpty() )
144 fileFilters += wxChar( '|' );
145
146 fileFilters += wxGetTranslation( loaders[ii].filter );
147
148 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
149 wxCHECK( plugin, false );
150 fileExtensions.push_back( plugin->GetFileExtension().ToStdString() );
151 }
152
153 fileFilters = _( "All KiCad Board Files" ) + AddFileExtListToFilter( fileExtensions )
154 + wxT( "|" ) + fileFilters;
155 }
156 else
157 {
158 wxString allWildcards;
159
160 for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
161 {
162 if( !fileFilters.IsEmpty() )
163 fileFilters += wxChar( '|' );
164
165 fileFilters += wxGetTranslation( loaders[ii].filter );
166
167 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
168 wxCHECK( plugin, false );
169 allWildcards += wxT( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) +
170 wxT( ";" );
171 }
172
173 fileFilters = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wxT( "|" ) +
174 fileFilters;
175 }
176
177
178 wxString path;
179 wxString name;
180
181 if( fileName.FileExists() )
182 {
183 path = fileName.GetPath();
184 name = fileName.GetFullName();
185 }
186 else
187 {
188 path = aParent->GetMruPath();
189
190 if( path.IsEmpty() )
192 // leave name empty
193 }
194
195 wxFileDialog dlg( aParent,
196 aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
197 path, name, fileFilters, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
198
199 if( dlg.ShowModal() == wxID_OK )
200 {
201 // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
202 // It's the only special case because of the duplicate use of the *.brd file extension.
203 // Other cases are clear because of unique file extensions.
204 *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
205 *aFileName = dlg.GetPath();
206 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
207 return true;
208 }
209 else
210 {
211 return false;
212 }
213}
214
215
225bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
226{
227 wxString wildcard = PcbFileWildcard();
228 wxFileName fn = *aFileName;
229
230 fn.SetExt( KiCadPcbFileExtension );
231
232 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
233 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
234
235// Add a "Create a project" checkbox in standalone mode and one isn't loaded
236#if wxCHECK_VERSION( 3, 1, 7 )
237 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
238
239 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
240 dlg.SetCustomizeHook( newProjectHook );
241#else
242 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
243 dlg.SetExtraControlCreator( &LEGACYFILEDLG_SAVE_PROJECT::Create );
244#endif
245
246
247 if( dlg.ShowModal() != wxID_OK )
248 return false;
249
250 fn = dlg.GetPath();
251
252 // always enforce filename extension, user may not have entered it.
253 fn.SetExt( KiCadPcbFileExtension );
254
255 *aFileName = fn.GetFullPath();
256
257#if wxCHECK_VERSION( 3, 1, 7 )
258 if( newProjectHook.IsAttachedToDialog() )
259 *aCreateProject = newProjectHook.GetCreateNewProject();
260 else if( !aParent->Prj().IsNullProject() )
261 *aCreateProject = true;
262#else
263 if( wxWindow* ec = dlg.GetExtraControl() )
264 *aCreateProject = static_cast<LEGACYFILEDLG_SAVE_PROJECT*>( ec )->GetValue();
265 else if( !aParent->Prj().IsNullProject() )
266 *aCreateProject = true;
267#endif
268
269 return true;
270}
271
272
273void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
274{
275 wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
276
277 if( !!fn )
278 {
279 int open_ctl = 0;
280
281 if( !wxFileName::IsFileReadable( fn ) )
282 {
283 if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
284 return;
285 }
286
287 OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
288 }
289}
290
291
292void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
293{
295}
296
297
298void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
299{
300 int id = event.GetId();
301 Files_io_from_id( id );
302}
303
304
306{
307 wxString msg;
308
309 switch( id )
310 {
311 case ID_LOAD_FILE:
312 {
313 int open_ctl = 0;
314 wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
315
316 return AskLoadBoardFileName( this, &open_ctl, &fileName, true )
317 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
318 }
319
321 {
322 int open_ctl = 1;
323 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
324
325 return AskLoadBoardFileName( this, &open_ctl, &fileName, false )
326 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
327 }
328
330 {
331 wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
332 wxFileName fn = currfn;
333
334 wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
335 fn.SetName( rec_name );
336
337 if( !fn.FileExists() )
338 {
339 msg.Printf( _( "Recovery file '%s' not found." ), fn.GetFullPath() );
340 DisplayInfoMessage( this, msg );
341 return false;
342 }
343
344 msg.Printf( _( "OK to load recovery file '%s'?" ), fn.GetFullPath() );
345
346 if( !IsOK( this, msg ) )
347 return false;
348
349 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
350
351 if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
352 {
353 // Re-set the name since name or extension was changed
354 GetBoard()->SetFileName( currfn.GetFullPath() );
355 UpdateTitle();
356 return true;
357 }
358
359 return false;
360 }
361
362 case ID_REVERT_BOARD:
363 {
364 wxFileName fn = Prj().AbsolutePath( GetBoard()->GetFileName() );
365
366 msg.Printf( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() );
367
368 if( !IsOK( this, msg ) )
369 return false;
370
371 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
372
373 ReleaseFile();
374
375 return OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
376 }
377
378 case ID_NEW_BOARD:
379 {
380 if( IsContentModified() )
381 {
382 wxFileName fileName = GetBoard()->GetFileName();
383 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
384 "continuing?" );
385
386 if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
387 [&]()->bool
388 {
389 return Files_io_from_id( ID_SAVE_BOARD );
390 } ) )
391 {
392 return false;
393 }
394 }
395 else if( !GetBoard()->IsEmpty() )
396 {
397 if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
398 return false;
399 }
400
402
404
406
407 mgr->SaveProject( mgr->Prj().GetProjectFullName() );
408 mgr->UnloadProject( &mgr->Prj() );
409
410 if( !Clear_Pcb( false ) )
411 return false;
412
414
416
417 OnModify();
418 return true;
419 }
420
421 case ID_SAVE_BOARD:
422 if( !GetBoard()->GetFileName().IsEmpty() )
423 {
424 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
425 {
426 m_autoSaveRequired = false;
427 return true;
428 }
429
430 return false;
431 }
432
434
435 case ID_COPY_BOARD_AS:
436 case ID_SAVE_BOARD_AS:
437 {
438 bool addToHistory = ( id == ID_SAVE_BOARD_AS );
439 wxString orig_name;
440
441 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
442
443 if( orig_name.IsEmpty() )
444 orig_name = NAMELESS_PROJECT;
445
446 wxFileName savePath( Prj().GetProjectFullName() );
447
448 if( !savePath.IsOk() || !savePath.IsDirWritable() )
449 {
450 savePath = GetMruPath();
451
452 if( !savePath.IsOk() || !savePath.IsDirWritable() )
454 }
455
456 wxFileName fn( savePath.GetPath(), orig_name, KiCadPcbFileExtension );
457 wxString filename = fn.GetFullPath();
458 bool createProject = false;
459 bool success = false;
460
461 if( AskSaveBoardFileName( this, &filename, &createProject ) )
462 {
463 if( id == ID_COPY_BOARD_AS )
464 {
465 success = SavePcbCopy( filename, createProject );
466 }
467 else
468 {
469 success = SavePcbFile( filename, addToHistory, createProject );
470
471 if( success )
472 m_autoSaveRequired = false;
473 }
474 }
475
476 return success;
477 }
478
479 default:
480 return false;
481 }
482}
483
484
485// The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
486// determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
487// bit flag.
488IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
489{
490 IO_MGR::PCB_FILE_T pluginType;
491
492 wxFileName fn = aFileName;
493
494 // Note: file extensions are expected to be in lower case.
495 // This is not always true, especially when importing files, so the string
496 // comparisons are case insensitive to try to find the suitable plugin.
497
498 if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
499 {
500 wxFileInputStream input( aFileName );
501 bool is_legacy = true;
502
503 if(input.IsOk() && !input.Eof() )
504 {
505 wxTextInputStream text( input );
506 wxString line = text.ReadLine();
507
508 if( !line.StartsWith( wxT( "PCBNEW" ) ) )
509 is_legacy = false;
510 }
511
512 // both legacy and eagle share a common file extension.
513 pluginType = ( aCtl & KICTL_EAGLE_BRD ) || !is_legacy ? IO_MGR::EAGLE : IO_MGR::LEGACY;
514 }
515 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
516 {
517 pluginType = IO_MGR::PCAD;
518 }
519 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
520 {
521 pluginType = IO_MGR::ALTIUM_DESIGNER;
522 }
523 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
524 {
526 }
527 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
528 {
529 pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
530 }
531 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
532 {
533 pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
534 }
535 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::FABMASTER ) ) == 0 )
536 {
537 pluginType = IO_MGR::FABMASTER;
538 }
539 else
540 {
541 pluginType = IO_MGR::KICAD_SEXP;
542 }
543
544 return pluginType;
545}
546
547
549{
550 PCB_LAYER_COLLECTOR collector;
551
552 collector.SetLayerId( Edge_Cuts );
553 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
554
555 int edgeWidth = -1;
556 bool mixed = false;
557
558 for( int i = 0; i < collector.GetCount(); i++ )
559 {
560 if( collector[i]->Type() == PCB_SHAPE_T )
561 {
562 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
563
564 if( edgeWidth != -1 && edgeWidth != itemWidth )
565 {
566 mixed = true;
567 edgeWidth = std::max( edgeWidth, itemWidth );
568 }
569 else
570 {
571 edgeWidth = itemWidth;
572 }
573 }
574 }
575
576 if( mixed )
577 {
578 // If they had different widths then we can't ensure that fills will be the same.
579 DisplayInfoMessage( this, _( "If the zones on this board are refilled the Copper Edge Clearance "
580 "setting will be used (see Board Setup > Design Rules > Constraints).\n"
581 "This may result in different fills from previous KiCad versions which "
582 "used the line thicknesses of the board boundary on the Edge Cuts "
583 "layer." ) );
584 }
585
586 return std::max( 0, edgeWidth / 2 );
587}
588
589
590bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
591{
592 // This is for python:
593 if( aFileSet.size() != 1 )
594 {
595 UTF8 msg = StrPrintf( "Pcbnew:%s() takes a single filename", __func__ );
596 DisplayError( this, msg );
597 return false;
598 }
599
600 wxString fullFileName( aFileSet[0] );
601 wxFileName wx_filename( fullFileName );
602 wxString msg;
603
604 if( Kiface().IsSingle() )
606
607 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
608 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
609
610 std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName );
611
612 if( !lockFile || lockFile->IsAnotherRunning() )
613 {
614 msg.Printf( _( "PCB '%s' is already open." ), wx_filename.GetFullName() );
615
616 if( !OverrideLock( this, msg ) )
617 return false;
618 }
619
620 if( IsContentModified() )
621 {
622 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
623 [&]() -> bool
624 {
625 return SavePcbFile( GetBoard()->GetFileName() );
626 } ) )
627 {
628 return false;
629 }
630 }
631
632 // Release the lock file, until the new file is actually loaded
633 ReleaseFile();
634
635 wxFileName pro = fullFileName;
636 pro.SetExt( ProjectFileExtension );
637
638 bool is_new = !wxFileName::IsFileReadable( fullFileName );
639
640 // If its a non-existent schematic and caller thinks it exists
641 if( is_new && !( aCtl & KICTL_CREATE ) )
642 {
643 // notify user that fullFileName does not exist, ask if user wants to create it.
644 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
645
646 if( !IsOK( this, msg ) )
647 return false;
648 }
649
650 // Get rid of any existing warnings about the old board
651 GetInfoBar()->Dismiss();
652
653 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Creating PCB" )
654 : _( "Loading PCB" ), 1 );
655
656 // No save prompt (we already prompted above), and only reset to a new blank board if new
657 Clear_Pcb( false, !is_new );
658
659 IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
660
661 bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
662
663 // Loading a project should only be done under carefully considered circumstances.
664
665 // The calling code should know not to ask me here to change projects unless
666 // it knows what consequences that will have on other KIFACEs running and using
667 // this same PROJECT. It can be very harmful if that calling code is stupid.
669
670 if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
671 {
672 // calls SaveProject
674
676 mgr->UnloadProject( &mgr->Prj() );
677
678 mgr->LoadProject( pro.GetFullPath() );
679
680 // Do not allow saving a project if one doesn't exist. This normally happens if we are
681 // standalone and opening a board that has been moved from its project folder.
682 // For converted projects, we don't want to set the read-only flag because we want a project
683 // to be saved for the new file in case things like netclasses got migrated.
684 Prj().SetReadOnly( !pro.Exists() && !converted );
685 }
686
687 // Clear the cache footprint list which may be project specific
689
690 if( is_new )
691 {
692 // Link the existing blank board to the new project
693 GetBoard()->SetProject( &Prj() );
694
695 GetBoard()->SetFileName( fullFileName );
696
697 OnModify();
698 }
699 else
700 {
701 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
702 PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
703
704 LAYER_REMAPPABLE_PLUGIN* layerRemappablePlugin =
705 dynamic_cast< LAYER_REMAPPABLE_PLUGIN* >( (PLUGIN*) pi );
706
707 if( layerRemappablePlugin )
708 {
709 layerRemappablePlugin->RegisterLayerMappingCallback(
710 std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, std::placeholders::_1 ) );
711 }
712
713 // This will rename the file if there is an autosave and the user want to recover
714 CheckForAutoSaveFile( fullFileName );
715
716 bool failedLoad = false;
717
718 try
719 {
720 STRING_UTF8_MAP props;
721 char xbuf[30];
722 char ybuf[30];
723
724 // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
725 snprintf( xbuf, sizeof(xbuf), "%d", GetPageSizeIU().x );
726 snprintf( ybuf, sizeof(ybuf), "%d", GetPageSizeIU().y );
727
728 props["page_width"] = xbuf;
729 props["page_height"] = ybuf;
730
732 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
733 {
734 KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
735
736 if( !aAction.IsEmpty() )
737 dlg.SetOKLabel( aAction );
738
739 dlg.DoNotShowCheckbox( aMessage, 0 );
740
741 return dlg.ShowModal() == wxID_OK;
742 } );
743
744#if USE_INSTRUMENTATION
745 // measure the time to load a BOARD.
746 unsigned startTime = GetRunningMicroSecs();
747#endif
748
749 loadedBoard = pi->Load( fullFileName, nullptr, &props, &Prj(), &progressReporter );
750
751#if USE_INSTRUMENTATION
752 unsigned stopTime = GetRunningMicroSecs();
753 printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
754#endif
755 }
756 catch( const FUTURE_FORMAT_ERROR& ffe )
757 {
758 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
759 progressReporter.Hide();
760 DisplayErrorMessage( this, msg, ffe.Problem() );
761
762 failedLoad = true;
763 }
764 catch( const IO_ERROR& ioe )
765 {
766 if( ioe.Problem() != wxT( "CANCEL" ) )
767 {
768 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
769 progressReporter.Hide();
770 DisplayErrorMessage( this, msg, ioe.What() );
771 }
772
773 failedLoad = true;
774 }
775 catch( const std::bad_alloc& )
776 {
777 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
778 progressReporter.Hide();
779 DisplayErrorMessage( this, msg, wxEmptyString );
780
781 failedLoad = true;
782 }
783
784 if( failedLoad )
785 {
786 // We didn't create a new blank board above, so do that now
787 Clear_Pcb( false );
788
789 return false;
790 }
791
792 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
793 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
794 // compiled.
795 Raise();
796
797 // Skip (possibly expensive) connectivity build here; we build it below after load
798 SetBoard( loadedBoard, false, &progressReporter );
799
800 if( GFootprintList.GetCount() == 0 )
801 GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
802
803 if( loadedBoard->m_LegacyDesignSettingsLoaded )
804 {
805 Prj().SetReadOnly( false );
806
807 // Before we had a copper edge clearance setting, the edge line widths could be used
808 // as a kludge to control them. So if there's no setting then infer it from the
809 // edge widths.
810 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
811 {
812 int edgeClearance = inferLegacyEdgeClearance( loadedBoard );
813 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
814 }
815
816 // On save; design settings will be removed from the board
817 loadedBoard->SetModified();
818 }
819
820 // Move legacy view settings to local project settings
821 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
822 {
824 loadedBoard->SetModified();
825 }
826
828 {
830 loadedBoard->SetModified();
831 }
832
833 // we should not ask PLUGINs to do these items:
834 loadedBoard->BuildListOfNets();
837
838 if( loadedBoard->IsModified() )
839 OnModify();
840 else
841 GetScreen()->SetContentModified( false );
842
843 if( ( pluginType == IO_MGR::LEGACY )
844 || ( pluginType == IO_MGR::KICAD_SEXP
846 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
847 {
850 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
851 "It will be converted to the new format when saved." ),
853 }
854
855 // Import footprints into a project-specific library
856 //==================================================
857 // TODO: This should be refactored out of here into somewhere specific to the Project Import
858 // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
859 if( aCtl & KICTL_IMPORT_LIB )
860 {
861 wxFileName loadedBoardFn( fullFileName );
862 wxString libNickName = loadedBoardFn.GetName();
863
864 // Extract a footprint library from the design and add it to the fp-lib-table
865 // The footprints are saved in a new .pretty library.
866 // If this library already exists, all previous footprints will be deleted
867 std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
868 wxString newLibPath = CreateNewProjectLibrary( libNickName );
869
870 // Only create the new library if CreateNewLibrary succeeded (note that this fails if
871 // the library already exists and the user aborts after seeing the warning message
872 // which prompts the user to continue with overwrite or abort)
873 if( newLibPath.Length() > 0 )
874 {
876
877 for( FOOTPRINT* footprint : loadedFootprints )
878 {
879 try
880 {
881 if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
882 {
883 footprint->SetReference( "REF**" );
884 piSexpr->FootprintSave( newLibPath, footprint );
885 delete footprint;
886 }
887 }
888 catch( const IO_ERROR& ioe )
889 {
890 wxLogError( _( "Error saving footprint %s to project specific library." )
891 + wxS( "\n%s" ),
892 footprint->GetFPID().GetUniStringLibItemName(),
893 ioe.What() );
894 }
895 }
896
897 FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
898 const wxString& project_env = PROJECT_VAR_NAME;
899 wxString rel_path, env_path;
900
901 wxASSERT_MSG( wxGetEnv( project_env, &env_path ),
902 wxT( "There is no project variable?" ) );
903
904 wxString result( newLibPath );
905
906 if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
907 rel_path = result;
908
909 FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
910 wxT( "KiCad" ), wxEmptyString );
911 prjlibtable->InsertRow( row );
912
913 wxString tblName = Prj().FootprintLibTblName();
914
915 try
916 {
917 Prj().PcbFootprintLibs()->Save( tblName );
918 }
919 catch( const IO_ERROR& ioe )
920 {
921 wxLogError( _( "Error saving project specific footprint library table." )
922 + wxS( "\n%s" ),
923 ioe.What() );
924 }
925
926 // Update footprint LIB_IDs to point to the just imported library
927 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
928 {
929 LIB_ID libId = footprint->GetFPID();
930
931 if( libId.GetLibItemName().empty() )
932 continue;
933
934 libId.SetLibNickname( libNickName );
935 footprint->SetFPID( libId );
936 }
937 }
938 }
939 }
940
941 {
942 wxFileName fn = fullFileName;
943
944 if( converted )
945 fn.SetExt( PcbFileExtension );
946
947 wxString fname = fn.GetFullPath();
948
949 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
950
951 GetBoard()->SetFileName( fname );
952 }
953
954 // Lock the file newly opened:
955 m_file_checker.reset( lockFile.release() );
956
957 if( !converted )
958 UpdateFileHistory( GetBoard()->GetFileName() );
959
960 std::vector<ZONE*> toFill;
961
962 // Rebuild list of nets (full ratsnest rebuild)
963 GetBoard()->BuildConnectivity( &progressReporter );
964
965 // Load project settings after setting up board; some of them depend on the nets list
967
968 // Syncs the UI (appearance panel, etc) with the loaded board and project
970
971 // Refresh the 3D view, if any
972 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
973
974 if( draw3DFrame )
975 draw3DFrame->NewDisplay();
976#if 0 && defined(DEBUG)
977 // Output the board object tree to stdout, but please run from command prompt:
978 GetBoard()->Show( 0, std::cout );
979#endif
980
981 // Re-fill any zones which had their legacy fills deleted on open
982
983 for( ZONE* zone : GetBoard()->Zones() )
984 {
985 if( zone->GetFlags() & CANDIDATE )
986 {
987 toFill.push_back( zone );
988 zone->ClearTempFlags();
989 }
990 }
991
992 if( toFill.size() )
993 {
994 BOARD_COMMIT commit( this );
995 ZONE_FILLER filler( GetBoard(), &commit );
996
997 progressReporter.Report( _( "Converting zone fills" ) );
998 filler.SetProgressReporter( &progressReporter );
999
1000 if( filler.Fill( toFill ) )
1001 commit.Push( _( "Convert Zone(s)" ), SKIP_CONNECTIVITY );
1002
1004 }
1005
1006 // from EDA_APPL which was first loaded BOARD only:
1007 {
1008 /* For an obscure reason the focus is lost after loading a board file
1009 * when starting up the process.
1010 * (seems due to the recreation of the layer manager after loading the file)
1011 * Give focus to main window and Drawpanel
1012 * must be done for these 2 windows (for an obscure reason ...)
1013 * Linux specific
1014 * This is more a workaround than a fix.
1015 */
1016 SetFocus();
1017 GetCanvas()->SetFocus();
1018 }
1019
1020 return true;
1021}
1022
1023
1024bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
1025 bool aChangeProject )
1026{
1027 // please, keep it simple. prompting goes elsewhere.
1028 wxFileName pcbFileName = aFileName;
1029
1030 if( pcbFileName.GetExt() == LegacyPcbFileExtension )
1031 pcbFileName.SetExt( KiCadPcbFileExtension );
1032
1033 // Write through symlinks, don't replace them
1035
1036 if( !IsWritable( pcbFileName ) )
1037 {
1038 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1039 pcbFileName.GetFullPath() );
1040
1041 DisplayError( this, msg );
1042 return false;
1043 }
1044
1045 // TODO: these will break if we ever go multi-board
1046 wxFileName projectFile( pcbFileName );
1047 wxFileName rulesFile( pcbFileName );
1048 wxString msg;
1049
1050 projectFile.SetExt( ProjectFileExtension );
1051 rulesFile.SetExt( DesignRulesFileExtension );
1052
1053 if( !projectFile.FileExists() && aChangeProject )
1054 {
1055 Prj().SetReadOnly( false );
1056 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1057 }
1058
1059 wxFileName currentRules( GetDesignRulesPath() );
1060
1061 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1062 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1063
1064 if( !msg.IsEmpty() )
1065 {
1066 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1067 rulesFile.GetFullPath() ) );
1068 }
1069
1070 if( projectFile.FileExists() )
1071 {
1072 // Save various DRC parameters, such as violation severities (which may have been
1073 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1075
1078 }
1079
1080 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew" ) );
1081 wxString upperTxt;
1082 wxString lowerTxt;
1083
1084 try
1085 {
1087
1088 pi->Save( tempFile, GetBoard(), nullptr );
1089 }
1090 catch( const IO_ERROR& ioe )
1091 {
1092 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1093 pcbFileName.GetFullPath(),
1094 ioe.What() ) );
1095
1096 lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile );
1097
1098 SetMsgPanel( upperTxt, lowerTxt );
1099
1100 // In case we started a file but didn't fully write it, clean up
1101 wxRemoveFile( tempFile );
1102
1103 return false;
1104 }
1105
1106 // If save succeeded, replace the original with what we just wrote
1107 if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
1108 {
1109 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n"
1110 "Failed to rename temporary file '%s." ),
1111 pcbFileName.GetFullPath(),
1112 tempFile ) );
1113
1114 lowerTxt.Printf( _( "Failed to rename temporary file '%s'." ),
1115 tempFile );
1116
1117 SetMsgPanel( upperTxt, lowerTxt );
1118
1119 return false;
1120 }
1121
1122 if( !Kiface().IsSingle() )
1123 {
1124 WX_STRING_REPORTER backupReporter( &upperTxt );
1125
1126 if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1127 upperTxt.clear();
1128 }
1129
1130 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1131
1132 // Update the lock in case it was a Save As
1133 LockFile( pcbFileName.GetFullPath() );
1134
1135 // Put the saved file in File History if requested
1136 if( addToHistory )
1137 UpdateFileHistory( GetBoard()->GetFileName() );
1138
1139 // Delete auto save file on successful save.
1140 wxFileName autoSaveFileName = pcbFileName;
1141
1142 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
1143
1144 if( autoSaveFileName.FileExists() )
1145 wxRemoveFile( autoSaveFileName.GetFullPath() );
1146
1147 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1148
1149 SetStatusText( lowerTxt, 0 );
1150
1151 // Get rid of the old version conversion warning, or any other dismissable warning :)
1153 m_infoBar->Dismiss();
1154
1155 if( m_infoBar->IsShown() && m_infoBar->HasCloseButton() )
1156 m_infoBar->Dismiss();
1157
1158 GetScreen()->SetContentModified( false );
1159 UpdateTitle();
1160 return true;
1161}
1162
1163
1164bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
1165{
1166 wxFileName pcbFileName = aFileName;
1167
1168 // Ensure the file ext is the right ext:
1169 pcbFileName.SetExt( KiCadPcbFileExtension );
1170
1171 if( !IsWritable( pcbFileName ) )
1172 {
1173 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1174 pcbFileName.GetFullPath() ) );
1175 return false;
1176 }
1177
1178 // Save various DRC parameters, such as violation severities (which may have been
1179 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1181
1183
1184 try
1185 {
1187
1188 wxASSERT( pcbFileName.IsAbsolute() );
1189
1190 pi->Save( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1191 }
1192 catch( const IO_ERROR& ioe )
1193 {
1194 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1195 pcbFileName.GetFullPath(),
1196 ioe.What() ) );
1197
1198 return false;
1199 }
1200
1201 wxFileName projectFile( pcbFileName );
1202 wxFileName rulesFile( pcbFileName );
1203 wxString msg;
1204
1205 projectFile.SetExt( ProjectFileExtension );
1206 rulesFile.SetExt( DesignRulesFileExtension );
1207
1208 if( aCreateProject && !projectFile.FileExists() )
1209 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1210
1211 wxFileName currentRules( GetDesignRulesPath() );
1212
1213 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1214 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1215
1216 if( !msg.IsEmpty() )
1217 {
1218 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1219 rulesFile.GetFullPath() ) );
1220 }
1221
1222 DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n%s" ),
1223 pcbFileName.GetFullPath() ) );
1224
1225 return true;
1226}
1227
1228
1230{
1231 wxFileName tmpFileName;
1232
1233 // Don't run autosave if content has not been modified
1234 if( !IsContentModified() )
1235 return true;
1236
1237 wxString title = GetTitle(); // Save frame title, that can be modified by the save process
1238
1239 if( GetBoard()->GetFileName().IsEmpty() )
1240 {
1241 tmpFileName = wxFileName( PATHS::GetDefaultUserProjectsPath(), NAMELESS_PROJECT,
1243 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1244 }
1245 else
1246 {
1247 tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1248 }
1249
1250 wxFileName autoSaveFileName = tmpFileName;
1251
1252 // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1253 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
1254
1255 if( !autoSaveFileName.IsOk() )
1256 return false;
1257
1258 // If the board file path is not writable, try writing to a platform specific temp file
1259 // path. If that path isn't writable, give up.
1260 if( !autoSaveFileName.IsDirWritable() )
1261 {
1262 autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1263
1264 if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1265 return false;
1266 }
1267
1268 wxLogTrace( traceAutoSave,
1269 wxT( "Creating auto save file <" ) + autoSaveFileName.GetFullPath() + wxT( ">" ) );
1270
1271 if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1272 {
1274 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1275 UpdateTitle();
1276 m_autoSaveRequired = false;
1277 m_autoSavePending = false;
1278
1279 if( !Kiface().IsSingle() &&
1280 GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1281 {
1283 }
1284
1285 SetTitle( title ); // Restore initial frame title
1286
1287 return true;
1288 }
1289
1290 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1291
1292 SetTitle( title ); // Restore initial frame title
1293
1294 return false;
1295}
1296
1297
1298bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1299{
1300 switch( (IO_MGR::PCB_FILE_T) aFileType )
1301 {
1303 case IO_MGR::EAGLE:
1304 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
1306
1307 default:
1308 return false;
1309 }
1310
1311 return false;
1312}
1313
const char * name
Definition: DXF_plotter.cpp:56
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
#define SKIP_CONNECTIVITY
Definition: board_commit.h:42
Pcbnew PLUGIN for CADSTAR PCB Archive (*.cpa) format: an ASCII format based on S-expressions.
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:342
GAL_SET m_LegacyVisibleItems
Definition: board.h:339
void BuildListOfNets()
Definition: board.h:744
void SetFileName(const wxString &aFileName)
Definition: board.h:300
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:162
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1528
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: board.h:338
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:172
const wxString & GetFileName() const
Definition: board.h:302
int GetFileFormatVersionAtLoad() const
Definition: board.h:363
const wxString & GetGenerator() const
Adds an item to the container.
Definition: board.h:366
void ClearProject()
Definition: board.cpp:210
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1519
bool m_LegacyCopperEdgeClearanceLoaded
Definition: board.h:343
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
static std::map< wxString, PCB_LAYER_ID > GetMapModal(wxWindow *aParent, const std::vector< INPUT_LAYER_DESC > &aLayerDesc)
Create and show a dialog (modal) and returns the data from it after completion.
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 void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
SETTINGS_MANAGER * GetSettingsManager() const
WX_INFOBAR * m_infoBar
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
void ClearFileHistory(FILE_HISTORY *aFileHistory=nullptr)
Removes all files from the file history.
wxString GetMruPath() const
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Checks if aFileName can be written.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetches the file name from the file history list.
static wxString GetAutoSaveFilePrefix()
void SetMruPath(const wxString &aPath)
WX_INFOBAR * GetInfoBar()
void ReleaseFile()
Release the current file marked in use.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
std::unique_ptr< wxSingleInstanceChecker > m_file_checker
void SetFocus() override
void SetModified()
Definition: eda_item.cpp:64
void ClearTempFlags()
Definition: eda_item.h:153
bool IsModified() const
Definition: eda_item.h:102
bool GetCreateNewProject() const
Gets if this hook has attached controls to a dialog box.
void ReadCacheFromFile(const wxString &aFilePath) override
unsigned GetCount() const
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:41
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
Definition: collectors.h:224
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
static const wxString GetFileExtension(PCB_FILE_T aFileType)
Return the file extension for aFileType.
Definition: io_mgr.cpp:109
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:54
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:55
@ ALTIUM_DESIGNER
Definition: io_mgr.h:60
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:56
@ ALTIUM_CIRCUIT_MAKER
Definition: io_mgr.h:62
@ PCAD
Definition: io_mgr.h:58
@ EAGLE
Definition: io_mgr.h:57
@ CADSTAR_PCB_ARCHIVE
Definition: io_mgr.h:63
@ FABMASTER
Definition: io_mgr.h:59
@ ALTIUM_CIRCUIT_STUDIO
Definition: io_mgr.h:61
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:46
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:76
int ShowModal() override
Definition: confirm.cpp:120
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Plugin class for import plugins that support remappable layers.
virtual void RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
< Helper widget to select whether a new project should be created for a file when saving
static wxWindow * Create(wxWindow *aParent)
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
static REPORTER & GetInstance()
Definition: reporter.cpp:117
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:139
static TOOL_ACTION repairBoard
Definition: pcb_actions.h:490
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
wxString CreateNewProjectLibrary(const wxString &aLibName=wxEmptyString, const wxString &aProposedName=wxEmptyString)
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
const wxSize GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
The main frame for Pcbnew.
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.
bool doAutoSave() override
Perform auto save when the board has been modified and not saved within the auto save interval.
void OnModify() override
Must be called after a board change to set the modified flag.
void SaveProjectSettings() override
Save changes to the project settings to the project (.pro) file.
void OnClearFileHistory(wxCommandEvent &aEvent)
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false)
Write the board data structures to aFileName.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
bool importFile(const wxString &aFileName, int aFileType)
Load the given filename but sets the path to the current project path.
void onBoardLoaded()
Update the state of the GUI after a new board is loaded or created.
bool Clear_Pcb(bool aQuery, bool aFinal=false)
Delete all and reinitialize the current board.
Definition: initpcb.cpp:43
bool Files_io_from_id(int aId)
Read and write board files according to aId.
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...
void Files_io(wxCommandEvent &event)
Call Files_io_from_id with the wxCommandEvent id.
void UpdateTitle()
Set the main window title bar text.
int inferLegacyEdgeClearance(BOARD *aBoard)
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Write the board data structures to a aFileName.
void ResolveDRCExclusions()
Update markers to match recorded exclusions.
void OnFileHistory(wxCommandEvent &event)
Collect all BOARD_ITEM objects on a given layer.
Definition: collectors.h:550
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.
Definition: collectors.cpp:649
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition: collectors.h:556
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:564
A base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:270
virtual void SetQueryUserCallback(std::function< bool(wxString aTitle, int aIcon, wxString aMessage, wxString aAction)> aCallback)
Registers a KIDIALOG callback for collecting info from the user.
Definition: io_mgr.h:285
virtual void Save(const wxString &aFileName, BOARD *aBoard, const STRING_UTF8_MAP *aProperties=nullptr)
Write aBoard to a storage file in a format that this PLUGIN implementation knows about or it can be u...
Definition: plugin.cpp:60
virtual BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Load information from some input file format that this PLUGIN implementation knows about into either ...
Definition: plugin.cpp:46
virtual void FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const STRING_UTF8_MAP *aProperties=nullptr)
Write aFootprint to an existing library located at aLibraryPath.
Definition: plugin.cpp:106
virtual std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints()
Return a container with the cached library footprints generated in the last call to Load.
Definition: plugin.cpp:54
virtual const wxString GetFileExtension() const =0
Returns the file extension for the PLUGIN.
virtual void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
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:127
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:120
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:324
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:155
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:150
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:305
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:138
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Sets the currently loaded project path and saves it (pointers remain valid) Note that this will not m...
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Saves a copy of the current project under the given path.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Saves a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Calls 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.
A name/value tuple with unique names and optional values.
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:170
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:71
bool empty() const
Definition: utf8.h:103
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Definition: wx_filename.cpp:92
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:289
bool HasCloseButton() const
Definition: wx_infobar.cpp:313
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:175
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:279
MESSAGE_TYPE GetMessageType() const
Definition: wx_infobar.h:100
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:142
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:164
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
Definition: zone_filler.cpp:71
bool Fill(std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Definition: zone_filler.cpp:89
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:380
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
bool OverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
Definition: confirm.cpp:175
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:352
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:260
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
This file is part of the common library.
#define _(s)
#define CANDIDATE
flag indicating that the structure is connected
FOOTPRINT_LIST_IMPL GFootprintList
The global footprint info table.
Definition: cvpcb.cpp:140
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition: gestfich.cpp:214
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:36
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:35
const std::string LegacyPcbFileExtension
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.
const std::string KiCadPcbFileExtension
#define PcbFileExtension
const std::string ProjectFileExtension
const std::string DesignRulesFileExtension
wxString LegacyPcbFileWildcard()
wxString CadstarPcbArchiveFileWildcard()
wxString AltiumDesignerPcbFileWildcard()
wxString PCadPcbFileWildcard()
wxString EaglePcbFileWildcard()
wxString FabmasterPcbFileWildcard()
wxString AltiumCircuitMakerPcbFileWildcard()
wxString AltiumCircuitStudioPcbFileWildcard()
wxString PcbFileWildcard()
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
@ ID_NEW_BOARD
Definition: id.h:76
@ ID_SAVE_BOARD
Definition: id.h:77
@ ID_LOAD_FILE
Definition: id.h:75
@ ID_SAVE_BOARD_AS
Definition: id.h:78
#define KICTL_CREATE
caller thinks requested project files may not exist.
Definition: kiway_player.h:82
#define KICTL_EAGLE_BRD
chosen *.brd file is Eagle according to user.
Definition: kiway_player.h:81
#define KICTL_IMPORT_LIB
import all footprints into a project library.
Definition: kiway_player.h:83
@ 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:226
@ Edge_Cuts
Definition: layer_ids.h:113
@ Rescue
Definition: layer_ids.h:133
#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:264
File locking utilities.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
Message panel definition file.
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition: gtk/app.cpp:58
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
Definition: pcb_plugin.h:133
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, int *aCtl, wxString *aFileName, bool aKicadFilesOnly)
Show a wxFileDialog asking for a BOARD filename to open.
IO_MGR::PCB_FILE_T plugin_type(const wxString &aFileName, int aCtl)
@ ID_IMPORT_NON_KICAD_BOARD
Definition: pcbnew_id.h:19
@ ID_REVERT_BOARD
Definition: pcbnew_id.h:18
@ ID_MENU_RECOVER_BOARD_AUTOSAVE
Definition: pcbnew_id.h:81
@ ID_COPY_BOARD_AS
Definition: pcbnew_id.h:17
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:39
#define NAMELESS_PROJECT
default name for nameless projects
Definition: project.h:42
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Class that computes missing connections on a PCB.
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
Definition: richio.cpp:84
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:175
wxLogTrace helper definitions.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
Definition of file extensions used in Kicad.