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-2021 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.cpp>
39#include <pcbnew_id.h>
40#include <io_mgr.h>
42#include <tool/tool_manager.h>
43#include <board.h>
44#include <wx/checkbox.h>
45#include <wx/stdpaths.h>
47#include <kiplatform/app.h>
49#include <widgets/infobar.h>
52#include <paths.h>
59#include <tools/pcb_actions.h>
60#include "footprint_info_impl.h"
61#include "board_commit.h"
62#include "zone_filler.h"
63#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
64
65#include <wx/wupdlock.h>
66#include <wx/filedlg.h>
67
68#if wxCHECK_VERSION( 3, 1, 7 )
69#include "widgets/filedlg_hook_save_project.h"
70#else
71#include "widgets/legacyfiledlg_save_project.h"
72#endif
73
74//#define USE_INSTRUMENTATION 1
75#define USE_INSTRUMENTATION 0
76
77
87bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, int* aCtl, wxString* aFileName,
88 bool aKicadFilesOnly )
89{
90 // This is a subset of all PLUGINs which are trusted to be able to
91 // load a BOARD. User may occasionally use the wrong plugin to load a
92 // *.brd file (since both legacy and eagle use *.brd extension),
93 // but eventually *.kicad_pcb will be more common than legacy *.brd files.
94
95 // clang-format off
96 static const struct
97 {
98 const wxString& filter;
99 IO_MGR::PCB_FILE_T pluginType;
100 } loaders[] =
101 {
102 // Current Kicad board files.
104
105 // Old Kicad board files.
107
108 // Import Altium Circuit Maker board files.
110
111 // Import Altium Circuit Studio board files.
113
114 // Import Altium Designer board files.
116
117 // Import Cadstar PCB Archive board files.
119
120 // Import Eagle board files.
122
123 // Import PCAD board files.
125
126 // Import Fabmaster board files.
128 };
129 // clang-format on
130
131 wxFileName fileName( *aFileName );
132 wxString fileFilters;
133
134 if( aKicadFilesOnly )
135 {
136 std::vector<std::string> fileExtensions;
137
138 for( unsigned ii = 0; ii < 2; ++ii )
139 {
140 if( !fileFilters.IsEmpty() )
141 fileFilters += wxChar( '|' );
142
143 fileFilters += wxGetTranslation( loaders[ii].filter );
144
145 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
146 wxCHECK( plugin, false );
147 fileExtensions.push_back( plugin->GetFileExtension().ToStdString() );
148 }
149
150 fileFilters = _( "All KiCad Board Files" ) + AddFileExtListToFilter( fileExtensions )
151 + wxT( "|" ) + fileFilters;
152 }
153 else
154 {
155 wxString allWildcards;
156
157 for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
158 {
159 if( !fileFilters.IsEmpty() )
160 fileFilters += wxChar( '|' );
161
162 fileFilters += wxGetTranslation( loaders[ii].filter );
163
164 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
165 wxCHECK( plugin, false );
166 allWildcards += wxT( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) + wxT( ";" );
167 }
168
169 fileFilters = _( "All supported formats|" ) + allWildcards + wxT( "|" ) + fileFilters;
170 }
171
172
173 wxString path;
174 wxString name;
175
176 if( fileName.FileExists() )
177 {
178 path = fileName.GetPath();
179 name = fileName.GetFullName();
180 }
181 else
182 {
183 path = aParent->GetMruPath();
184
185 if( path.IsEmpty() )
187 // leave name empty
188 }
189
190 wxFileDialog dlg( aParent,
191 aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
192 path, name, fileFilters, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
193
194 if( dlg.ShowModal() == wxID_OK )
195 {
196 // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
197 // It's the only special case because of the duplicate use of the *.brd file extension.
198 // Other cases are clear because of unique file extensions.
199 *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
200 *aFileName = dlg.GetPath();
201 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
202 return true;
203 }
204 else
205 {
206 return false;
207 }
208}
209
210
220bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
221{
222 wxString wildcard = PcbFileWildcard();
223 wxFileName fn = *aFileName;
224
225 fn.SetExt( KiCadPcbFileExtension );
226
227 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
228 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
229
230#if wxCHECK_VERSION( 3, 1, 7 )
231 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
232 bool checkHook = false;
233#endif
234
235#if wxCHECK_VERSION( 3, 1, 7 )
236 dlg.SetCustomizeHook( newProjectHook );
237 checkHook = true;
238#else
239 // Add a "Create a project" checkbox in standalone mode and one isn't loaded
240 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
241 dlg.SetExtraControlCreator( &LEGACYFILEDLG_SAVE_PROJECT::Create );
242#endif
243
244
245 if( dlg.ShowModal() != wxID_OK )
246 return false;
247
248 fn = dlg.GetPath();
249
250 // always enforce filename extension, user may not have entered it.
251 fn.SetExt( KiCadPcbFileExtension );
252
253 *aFileName = fn.GetFullPath();
254
255#if wxCHECK_VERSION( 3, 1, 7 )
256 if( checkHook )
257 *aCreateProject = newProjectHook.GetCreateNewProject();
258 else if( !aParent->Prj().IsNullProject() )
259 *aCreateProject = true;
260#else
261 if( wxWindow* ec = dlg.GetExtraControl() )
262 *aCreateProject = static_cast<LEGACYFILEDLG_SAVE_PROJECT*>( ec )->GetValue();
263 else if( !aParent->Prj().IsNullProject() )
264 *aCreateProject = true;
265#endif
266
267 return true;
268}
269
270
271void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
272{
273 wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
274
275 if( !!fn )
276 {
277 int open_ctl = 0;
278
279 if( !wxFileName::IsFileReadable( fn ) )
280 {
281 if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
282 return;
283 }
284
285 OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
286 }
287}
288
289
290void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
291{
293}
294
295
296void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
297{
298 int id = event.GetId();
299 Files_io_from_id( id );
300}
301
302
304{
305 wxString msg;
306
307 switch( id )
308 {
309 case ID_LOAD_FILE:
310 {
311 int open_ctl = 0;
312 wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
313
314 return AskLoadBoardFileName( this, &open_ctl, &fileName, true )
315 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
316 }
317
319 {
320 int open_ctl = 1;
321 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
322
323 return AskLoadBoardFileName( this, &open_ctl, &fileName, false )
324 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
325 }
326
328 {
329 wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
330 wxFileName fn = currfn;
331
332 wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
333 fn.SetName( rec_name );
334
335 if( !fn.FileExists() )
336 {
337 msg.Printf( _( "Recovery file '%s' not found." ), fn.GetFullPath() );
338 DisplayInfoMessage( this, msg );
339 return false;
340 }
341
342 msg.Printf( _( "OK to load recovery file '%s'?" ), fn.GetFullPath() );
343
344 if( !IsOK( this, msg ) )
345 return false;
346
347 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
348
349 if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
350 {
351 // Re-set the name since name or extension was changed
352 GetBoard()->SetFileName( currfn.GetFullPath() );
353 UpdateTitle();
354 return true;
355 }
356
357 return false;
358 }
359
360 case ID_REVERT_BOARD:
361 {
362 wxFileName fn = Prj().AbsolutePath( GetBoard()->GetFileName() );
363
364 msg.Printf( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() );
365
366 if( !IsOK( this, msg ) )
367 return false;
368
369 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
370
371 ReleaseFile();
372
373 return OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
374 }
375
376 case ID_NEW_BOARD:
377 {
378 if( IsContentModified() )
379 {
380 wxFileName fileName = GetBoard()->GetFileName();
381 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
382 "continuing?" );
383
384 if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
385 [&]()->bool
386 {
387 return Files_io_from_id( ID_SAVE_BOARD );
388 } ) )
389 {
390 return false;
391 }
392 }
393 else if( !GetBoard()->IsEmpty() )
394 {
395 if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
396 return false;
397 }
398
400
402
404
405 mgr->SaveProject( mgr->Prj().GetProjectFullName() );
406 mgr->UnloadProject( &mgr->Prj() );
407
408 if( !Clear_Pcb( false ) )
409 return false;
410
412
414
415 OnModify();
416 return true;
417 }
418
419 case ID_SAVE_BOARD:
420 if( !GetBoard()->GetFileName().IsEmpty() )
421 return SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
422
424
425 case ID_COPY_BOARD_AS:
426 case ID_SAVE_BOARD_AS:
427 {
428 bool addToHistory = ( id == ID_SAVE_BOARD_AS );
429 wxString orig_name;
430
431 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
432
433 if( orig_name.IsEmpty() )
434 orig_name = NAMELESS_PROJECT;
435
436 wxFileName savePath( Prj().GetProjectFullName() );
437
438 if( !savePath.IsOk() || !savePath.IsDirWritable() )
439 {
440 savePath = GetMruPath();
441
442 if( !savePath.IsOk() || !savePath.IsDirWritable() )
444 }
445
446 wxFileName fn( savePath.GetPath(), orig_name, KiCadPcbFileExtension );
447 wxString filename = fn.GetFullPath();
448 bool createProject = false;
449
450 if( AskSaveBoardFileName( this, &filename, &createProject ) )
451 {
452 if( id == ID_COPY_BOARD_AS )
453 return SavePcbCopy( filename, createProject );
454 else
455 return SavePcbFile( filename, addToHistory, createProject );
456 }
457
458 return false;
459 }
460
461 default:
462 return false;
463 }
464}
465
466
467// The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
468// determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
469// bit flag.
470IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
471{
472 IO_MGR::PCB_FILE_T pluginType;
473
474 wxFileName fn = aFileName;
475
476 // Note: file extensions are expected to be in lower case.
477 // This is not always true, especially when importing files, so the string
478 // comparisons are case insensitive to try to find the suitable plugin.
479
480 if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
481 {
482 // both legacy and eagle share a common file extension.
483 pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
484 }
485 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
486 {
487 pluginType = IO_MGR::PCAD;
488 }
489 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
490 {
491 pluginType = IO_MGR::ALTIUM_DESIGNER;
492 }
493 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
494 {
496 }
497 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
498 {
499 pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
500 }
501 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
502 {
503 pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
504 }
505 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::FABMASTER ) ) == 0 )
506 {
507 pluginType = IO_MGR::FABMASTER;
508 }
509 else
510 {
511 pluginType = IO_MGR::KICAD_SEXP;
512 }
513
514 return pluginType;
515}
516
517
519{
520 PCB_LAYER_COLLECTOR collector;
521
522 collector.SetLayerId( Edge_Cuts );
523 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
524
525 int edgeWidth = -1;
526 bool mixed = false;
527
528 for( int i = 0; i < collector.GetCount(); i++ )
529 {
530 if( collector[i]->Type() == PCB_SHAPE_T )
531 {
532 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
533
534 if( edgeWidth != -1 && edgeWidth != itemWidth )
535 {
536 mixed = true;
537 edgeWidth = std::max( edgeWidth, itemWidth );
538 }
539 else
540 {
541 edgeWidth = itemWidth;
542 }
543 }
544 }
545
546 if( mixed )
547 {
548 // If they had different widths then we can't ensure that fills will be the same.
549 wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance "
550 "setting will be used (see Board Setup > Design Rules > Constraints).\n"
551 "This may result in different fills from previous KiCad versions which "
552 "used the line thicknesses of the board boundary on the Edge Cuts "
553 "layer." ),
554 _( "Edge Clearance Warning" ), wxOK | wxICON_WARNING, this );
555 }
556
557 return std::max( 0, edgeWidth / 2 );
558}
559
560
561bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
562{
563 // This is for python:
564 if( aFileSet.size() != 1 )
565 {
566 UTF8 msg = StrPrintf( "Pcbnew:%s() takes a single filename", __func__ );
567 DisplayError( this, msg );
568 return false;
569 }
570
571 wxString fullFileName( aFileSet[0] );
572 wxFileName wx_filename( fullFileName );
573 wxString msg;
574
575 if( Kiface().IsSingle() )
577
578 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
579 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
580
581 std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName );
582
583 if( !lockFile || lockFile->IsAnotherRunning() )
584 {
585 msg.Printf( _( "PCB '%s' is already open." ), wx_filename.GetFullName() );
586
587 if( !OverrideLock( this, msg ) )
588 return false;
589 }
590
591 if( IsContentModified() )
592 {
593 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
594 [&]() -> bool
595 {
596 return SavePcbFile( GetBoard()->GetFileName() );
597 } ) )
598 {
599 return false;
600 }
601 }
602
603 // Release the lock file, until the new file is actually loaded
604 ReleaseFile();
605
606 wxFileName pro = fullFileName;
607 pro.SetExt( ProjectFileExtension );
608
609 bool is_new = !wxFileName::IsFileReadable( fullFileName );
610
611 // If its a non-existent schematic and caller thinks it exists
612 if( is_new && !( aCtl & KICTL_CREATE ) )
613 {
614 // notify user that fullFileName does not exist, ask if user wants to create it.
615 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
616
617 if( !IsOK( this, msg ) )
618 return false;
619 }
620
621 // Get rid of any existing warnings about the old board
622 GetInfoBar()->Dismiss();
623
624 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Creating PCB" )
625 : _( "Loading PCB" ), 1 );
626
627 // No save prompt (we already prompted above), and only reset to a new blank board if new
628 Clear_Pcb( false, !is_new );
629
630 IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
631
632 bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
633
634 // Loading a project should only be done under carefully considered circumstances.
635
636 // The calling code should know not to ask me here to change projects unless
637 // it knows what consequences that will have on other KIFACEs running and using
638 // this same PROJECT. It can be very harmful if that calling code is stupid.
640
641 if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
642 {
643 // calls SaveProject
645
647 mgr->UnloadProject( &mgr->Prj() );
648
649 mgr->LoadProject( pro.GetFullPath() );
650
651 // Do not allow saving a project if one doesn't exist. This normally happens if we are
652 // standalone and opening a board that has been moved from its project folder.
653 // For converted projects, we don't want to set the read-only flag because we want a project
654 // to be saved for the new file in case things like netclasses got migrated.
655 Prj().SetReadOnly( !pro.Exists() && !converted );
656 }
657
658 // Clear the cache footprint list which may be project specific
660
661 if( is_new )
662 {
663 // Link the existing blank board to the new project
664 GetBoard()->SetProject( &Prj() );
665
666 GetBoard()->SetFileName( fullFileName );
667
668 OnModify();
669 }
670 else
671 {
672 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
673 PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
674
675 LAYER_REMAPPABLE_PLUGIN* layerRemappablePlugin =
676 dynamic_cast< LAYER_REMAPPABLE_PLUGIN* >( (PLUGIN*) pi );
677
678 if( layerRemappablePlugin )
679 {
680 layerRemappablePlugin->RegisterLayerMappingCallback(
681 std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, std::placeholders::_1 ) );
682 }
683
684 // This will rename the file if there is an autosave and the user want to recover
685 CheckForAutoSaveFile( fullFileName );
686
687 bool failedLoad = false;
688
689 try
690 {
691 PROPERTIES props;
692 char xbuf[30];
693 char ybuf[30];
694
695 // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
696 sprintf( xbuf, "%d", GetPageSizeIU().x );
697 sprintf( ybuf, "%d", GetPageSizeIU().y );
698
699 props["page_width"] = xbuf;
700 props["page_height"] = ybuf;
701
703 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
704 {
705 KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
706
707 if( !aAction.IsEmpty() )
708 dlg.SetOKLabel( aAction );
709
710 dlg.DoNotShowCheckbox( aMessage, 0 );
711
712 return dlg.ShowModal() == wxID_OK;
713 } );
714
715#if USE_INSTRUMENTATION
716 // measure the time to load a BOARD.
717 unsigned startTime = GetRunningMicroSecs();
718#endif
719
720 loadedBoard = pi->Load( fullFileName, nullptr, &props, &Prj(), &progressReporter );
721
722#if USE_INSTRUMENTATION
723 unsigned stopTime = GetRunningMicroSecs();
724 printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
725#endif
726 }
727 catch( const FUTURE_FORMAT_ERROR& ffe )
728 {
729 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
730 progressReporter.Hide();
731 DisplayErrorMessage( this, msg, ffe.Problem() );
732
733 failedLoad = true;
734 }
735 catch( const IO_ERROR& ioe )
736 {
737 if( ioe.Problem() != wxT( "CANCEL" ) )
738 {
739 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
740 progressReporter.Hide();
741 DisplayErrorMessage( this, msg, ioe.What() );
742 }
743
744 failedLoad = true;
745 }
746 catch( const std::bad_alloc& )
747 {
748 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
749 progressReporter.Hide();
750 DisplayErrorMessage( this, msg, wxEmptyString );
751
752 failedLoad = true;
753 }
754
755 if( failedLoad )
756 {
757 // We didn't create a new blank board above, so do that now
758 Clear_Pcb( false );
759
760 return false;
761 }
762
763 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
764 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
765 // compiled.
766 Raise();
767
768 // Skip (possibly expensive) connectivity build here; we build it below after load
769 SetBoard( loadedBoard, false, &progressReporter );
770
771 if( GFootprintList.GetCount() == 0 )
772 GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
773
774 if( loadedBoard->m_LegacyDesignSettingsLoaded )
775 {
776 Prj().SetReadOnly( false );
777
778 // Before we had a copper edge clearance setting, the edge line widths could be used
779 // as a kludge to control them. So if there's no setting then infer it from the
780 // edge widths.
781 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
782 {
783 int edgeClearance = inferLegacyEdgeClearance( loadedBoard );
784 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
785 }
786
787 // On save; design settings will be removed from the board
788 loadedBoard->SetModified();
789 }
790
791 // Move legacy view settings to local project settings
792 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
793 {
795 loadedBoard->SetModified();
796 }
797
799 {
801 loadedBoard->SetModified();
802 }
803
804 // we should not ask PLUGINs to do these items:
805 loadedBoard->BuildListOfNets();
808
809 if( loadedBoard->IsModified() )
810 OnModify();
811 else
812 GetScreen()->SetContentModified( false );
813
814 if( ( pluginType == IO_MGR::LEGACY )
815 || ( pluginType == IO_MGR::KICAD_SEXP
817 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
818 {
821 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
822 "It will be converted to the new format when saved." ),
824 }
825
826 // Import footprints into a project-specific library
827 //==================================================
828 // TODO: This should be refactored out of here into somewhere specific to the Project Import
829 // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
830 if( aCtl & KICTL_IMPORT_LIB )
831 {
832 wxFileName loadedBoardFn( fullFileName );
833 wxString libNickName = loadedBoardFn.GetName();
834
835 // Extract a footprint library from the design and add it to the fp-lib-table
836 // The footprints are saved in a new .pretty library.
837 // If this library already exists, all previous footprints will be deleted
838 std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
839 wxString newLibPath = CreateNewProjectLibrary( libNickName );
840
841 // Only create the new library if CreateNewLibrary succeeded (note that this fails if
842 // the library already exists and the user aborts after seeing the warning message
843 // which prompts the user to continue with overwrite or abort)
844 if( newLibPath.Length() > 0 )
845 {
847
848 for( FOOTPRINT* footprint : loadedFootprints )
849 {
850 try
851 {
852 if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
853 {
854 footprint->SetReference( "REF**" );
855 piSexpr->FootprintSave( newLibPath, footprint );
856 delete footprint;
857 }
858 }
859 catch( const IO_ERROR& ioe )
860 {
861 wxLogError( _( "Error saving footprint %s to project specific library." )
862 + wxS( "\n%s" ),
863 footprint->GetFPID().GetUniStringLibItemName(),
864 ioe.What() );
865 }
866 }
867
868 FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
869 const wxString& project_env = PROJECT_VAR_NAME;
870 wxString rel_path, env_path;
871
872 wxASSERT_MSG( wxGetEnv( project_env, &env_path ),
873 wxT( "There is no project variable?" ) );
874
875 wxString result( newLibPath );
876
877 if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
878 rel_path = result;
879
880 FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
881 wxT( "KiCad" ), wxEmptyString );
882 prjlibtable->InsertRow( row );
883
884 wxString tblName = Prj().FootprintLibTblName();
885
886 try
887 {
888 Prj().PcbFootprintLibs()->Save( tblName );
889 }
890 catch( const IO_ERROR& ioe )
891 {
892 wxLogError( _( "Error saving project specific footprint library table." )
893 + wxS( "\n%s" ),
894 ioe.What() );
895 }
896
897 // Update footprint LIB_IDs to point to the just imported library
898 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
899 {
900 LIB_ID libId = footprint->GetFPID();
901
902 if( libId.GetLibItemName().empty() )
903 continue;
904
905 libId.SetLibNickname( libNickName );
906 footprint->SetFPID( libId );
907 }
908 }
909 }
910 }
911
912 {
913 wxFileName fn = fullFileName;
914
915 if( converted )
916 fn.SetExt( PcbFileExtension );
917
918 wxString fname = fn.GetFullPath();
919
920 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
921
922 GetBoard()->SetFileName( fname );
923 }
924
925 // Lock the file newly opened:
926 m_file_checker.reset( lockFile.release() );
927
928 if( !converted )
929 UpdateFileHistory( GetBoard()->GetFileName() );
930
931 std::vector<ZONE*> toFill;
932
933 // Rebuild list of nets (full ratsnest rebuild)
934 GetBoard()->BuildConnectivity( &progressReporter );
935
936 // Load project settings after setting up board; some of them depend on the nets list
938
939 // Syncs the UI (appearance panel, etc) with the loaded board and project
941
942 // Refresh the 3D view, if any
943 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
944
945 if( draw3DFrame )
946 draw3DFrame->NewDisplay();
947#if 0 && defined(DEBUG)
948 // Output the board object tree to stdout, but please run from command prompt:
949 GetBoard()->Show( 0, std::cout );
950#endif
951
952 // Re-fill any zones which had their legacy fills deleted on open
953
954 for( ZONE* zone : GetBoard()->Zones() )
955 {
956 if( zone->GetFlags() & CANDIDATE )
957 {
958 toFill.push_back( zone );
959 zone->ClearTempFlags();
960 }
961 }
962
963 if( toFill.size() )
964 {
965 BOARD_COMMIT commit( this );
966 ZONE_FILLER filler( GetBoard(), &commit );
967
968 progressReporter.Report( _( "Converting zone fills" ) );
969 filler.SetProgressReporter( &progressReporter );
970
971 if( filler.Fill( toFill ) )
972 commit.Push( _( "Convert Zone(s)" ), SKIP_CONNECTIVITY );
973
974 GetBoard()->BuildConnectivity( &progressReporter );
975 }
976
977 // from EDA_APPL which was first loaded BOARD only:
978 {
979 /* For an obscure reason the focus is lost after loading a board file
980 * when starting up the process.
981 * (seems due to the recreation of the layer manager after loading the file)
982 * Give focus to main window and Drawpanel
983 * must be done for these 2 windows (for an obscure reason ...)
984 * Linux specific
985 * This is more a workaround than a fix.
986 */
987 SetFocus();
988 GetCanvas()->SetFocus();
989 }
990
991 return true;
992}
993
994
995bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
996 bool aChangeProject )
997{
998 // please, keep it simple. prompting goes elsewhere.
999 wxFileName pcbFileName = aFileName;
1000
1001 if( pcbFileName.GetExt() == LegacyPcbFileExtension )
1002 pcbFileName.SetExt( KiCadPcbFileExtension );
1003
1004 // Write through symlinks, don't replace them
1006
1007 if( !IsWritable( pcbFileName ) )
1008 {
1009 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1010 pcbFileName.GetFullPath() );
1011
1012 DisplayError( this, msg );
1013 return false;
1014 }
1015
1016 // TODO: these will break if we ever go multi-board
1017 wxFileName projectFile( pcbFileName );
1018 wxFileName rulesFile( pcbFileName );
1019 wxString msg;
1020
1021 projectFile.SetExt( ProjectFileExtension );
1022 rulesFile.SetExt( DesignRulesFileExtension );
1023
1024 if( !projectFile.FileExists() && aChangeProject )
1025 {
1026 Prj().SetReadOnly( false );
1027 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1028 }
1029
1030 wxFileName currentRules( GetDesignRulesPath() );
1031
1032 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1033 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1034
1035 if( !msg.IsEmpty() )
1036 {
1037 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1038 rulesFile.GetFullPath() ) );
1039 }
1040
1041 if( projectFile.FileExists() )
1042 {
1043 // Save various DRC parameters, such as violation severities (which may have been
1044 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1046
1049 }
1050
1051 wxStandardPaths& paths = wxStandardPaths::Get();
1052 wxString tempFile = wxFileName::CreateTempFileName(
1053 paths.GetTempDir() + wxFileName::GetPathSeparator() + wxT( "pcbnew" ) );
1054 wxString upperTxt;
1055 wxString lowerTxt;
1056
1057 try
1058 {
1060
1061 pi->Save( tempFile, GetBoard(), nullptr );
1062 }
1063 catch( const IO_ERROR& ioe )
1064 {
1065 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1066 pcbFileName.GetFullPath(),
1067 ioe.What() ) );
1068
1069 lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile );
1070
1071 SetMsgPanel( upperTxt, lowerTxt );
1072
1073 // In case we started a file but didn't fully write it, clean up
1074 wxRemoveFile( tempFile );
1075
1076 return false;
1077 }
1078
1079 // If save succeeded, replace the original with what we just wrote
1080 if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
1081 {
1082 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n"
1083 "Failed to rename temporary file '%s." ),
1084 pcbFileName.GetFullPath(),
1085 tempFile ) );
1086
1087 lowerTxt.Printf( _( "Failed to rename temporary file '%s'." ),
1088 tempFile );
1089
1090 SetMsgPanel( upperTxt, lowerTxt );
1091
1092 return false;
1093 }
1094
1095 if( !Kiface().IsSingle() )
1096 {
1097 WX_STRING_REPORTER backupReporter( &upperTxt );
1098
1099 if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1100 upperTxt.clear();
1101 }
1102
1103 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1104
1105 // Update the lock in case it was a Save As
1106 LockFile( pcbFileName.GetFullPath() );
1107
1108 // Put the saved file in File History if requested
1109 if( addToHistory )
1110 UpdateFileHistory( GetBoard()->GetFileName() );
1111
1112 // Delete auto save file on successful save.
1113 wxFileName autoSaveFileName = pcbFileName;
1114
1115 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
1116
1117 if( autoSaveFileName.FileExists() )
1118 wxRemoveFile( autoSaveFileName.GetFullPath() );
1119
1120 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1121
1122 SetStatusText( lowerTxt, 0 );
1123
1124 // Get rid of the old version conversion warning, or any other dismissable warning :)
1126 m_infoBar->Dismiss();
1127
1128 if( m_infoBar->IsShown() && m_infoBar->HasCloseButton() )
1129 m_infoBar->Dismiss();
1130
1131 GetScreen()->SetContentModified( false );
1132 UpdateTitle();
1133 return true;
1134}
1135
1136
1137bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
1138{
1139 wxFileName pcbFileName = aFileName;
1140
1141 // Ensure the file ext is the right ext:
1142 pcbFileName.SetExt( KiCadPcbFileExtension );
1143
1144 if( !IsWritable( pcbFileName ) )
1145 {
1146 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1147 pcbFileName.GetFullPath() ) );
1148 return false;
1149 }
1150
1151 // Save various DRC parameters, such as violation severities (which may have been
1152 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1154
1156
1157 try
1158 {
1160
1161 wxASSERT( pcbFileName.IsAbsolute() );
1162
1163 pi->Save( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1164 }
1165 catch( const IO_ERROR& ioe )
1166 {
1167 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1168 pcbFileName.GetFullPath(),
1169 ioe.What() ) );
1170
1171 return false;
1172 }
1173
1174 wxFileName projectFile( pcbFileName );
1175 wxFileName rulesFile( pcbFileName );
1176 wxString msg;
1177
1178 projectFile.SetExt( ProjectFileExtension );
1179 rulesFile.SetExt( DesignRulesFileExtension );
1180
1181 if( aCreateProject && !projectFile.FileExists() )
1182 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1183
1184 wxFileName currentRules( GetDesignRulesPath() );
1185
1186 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1187 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1188
1189 if( !msg.IsEmpty() )
1190 {
1191 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1192 rulesFile.GetFullPath() ) );
1193 }
1194
1195 DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n%s" ),
1196 pcbFileName.GetFullPath() ) );
1197
1198 return true;
1199}
1200
1201
1203{
1204 wxFileName tmpFileName;
1205
1206 // Don't run autosave if content has not been modified
1207 if( !IsContentModified() )
1208 return true;
1209
1210 wxString title = GetTitle(); // Save frame title, that can be modified by the save process
1211
1212 if( GetBoard()->GetFileName().IsEmpty() )
1213 {
1214 tmpFileName = wxFileName( PATHS::GetDefaultUserProjectsPath(), NAMELESS_PROJECT,
1216 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1217 }
1218 else
1219 {
1220 tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1221 }
1222
1223 wxFileName autoSaveFileName = tmpFileName;
1224
1225 // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1226 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
1227
1228 if( !autoSaveFileName.IsOk() )
1229 return false;
1230
1231 // If the board file path is not writable, try writing to a platform specific temp file
1232 // path. If that path isn't writable, give up.
1233 if( !autoSaveFileName.IsDirWritable() )
1234 {
1235 autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1236
1237 if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1238 return false;
1239 }
1240
1241 wxLogTrace( traceAutoSave,
1242 wxT( "Creating auto save file <" ) + autoSaveFileName.GetFullPath() + wxT( ">" ) );
1243
1244 if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1245 {
1247 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1248 UpdateTitle();
1249 m_autoSaveState = false;
1250
1251 if( !Kiface().IsSingle() &&
1252 GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1253 {
1255 }
1256
1257 SetTitle( title ); // Restore initial frame title
1258
1259 return true;
1260 }
1261
1262 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1263
1264 SetTitle( title ); // Restore initial frame title
1265
1266 return false;
1267}
1268
1269
1270bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1271{
1272 switch( (IO_MGR::PCB_FILE_T) aFileType )
1273 {
1275 case IO_MGR::EAGLE:
1276 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
1278
1279 default:
1280 return false;
1281 }
1282
1283 return false;
1284}
1285
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:742
void SetFileName(const wxString &aFileName)
Definition: board.h:300
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1459
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:162
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:196
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:617
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1450
bool m_LegacyCopperEdgeClearanceLoaded
Definition: board.h:343
void BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:155
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:155
bool IsModified() const
Definition: eda_item.h:102
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:56
int ShowModal() override
Definition: confirm.cpp:100
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:101
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:482
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 PROPERTIES *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 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 FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const PROPERTIES *aProperties=nullptr)
Write aFootprint to an existing library located at aLibraryPath.
Definition: plugin.cpp:108
virtual BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *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 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:126
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:119
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:318
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:154
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:149
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:304
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:137
A name/value tuple with unique names and optional values.
Definition: properties.h:34
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.
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:85
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:286
bool HasCloseButton() const
Definition: infobar.cpp:310
@ 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: infobar.cpp:175
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: infobar.cpp:276
MESSAGE_TYPE GetMessageType() const
Definition: infobar.h:100
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: 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:72
bool Fill(std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Definition: zone_filler.cpp:90
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:342
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
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:155
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:320
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:240
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299
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
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:130
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:38
#define NAMELESS_PROJECT
default name for nameless projects
Definition: project.h:41
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.