KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/files.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 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 <string>
27
28#include <confirm.h>
29#include <core/arraydim.h>
30#include <gestfich.h>
31#include <pcb_edit_frame.h>
34#include <fp_lib_table.h>
35#include <kiface_base.h>
36#include <macros.h>
37#include <trace_helpers.h>
38#include <lockfile.h>
39#include <wx/snglinst.h>
41#include <pcbnew_id.h>
42#include <io_mgr.h>
44#include <tool/tool_manager.h>
45#include <board.h>
46#include <kiplatform/app.h>
48#include <widgets/wx_infobar.h>
51#include <paths.h>
52#include <pgm_base.h>
54#include <project_pcb.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 <kiplatform/io.h>
67
68#include <wx/stdpaths.h>
69#include <wx/filedlg.h>
70#include <wx/txtstrm.h>
71
72#include "widgets/filedlg_hook_save_project.h"
73
74//#define USE_INSTRUMENTATION 1
75#define USE_INSTRUMENTATION 0
76
77
87bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 )
88{
89 std::vector<PLUGIN_FILE_DESC> descriptions;
90
91 for( const auto& plugin : IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins() )
92 {
93 bool isKiCad = plugin.m_type == IO_MGR::KICAD_SEXP || plugin.m_type == IO_MGR::LEGACY;
94
95 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
96 continue;
97
98 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
99 continue;
100
101 // release the PLUGIN even if an exception is thrown.
102 PLUGIN::RELEASER pi( plugin.m_createFunc() );
103 wxCHECK( pi, false );
104
105 const PLUGIN_FILE_DESC& desc = pi->GetBoardFileDesc();
106
107 if( desc.m_FileExtensions.empty() )
108 continue;
109
110 descriptions.emplace_back( desc );
111 }
112
113 wxString fileFiltersStr;
114 std::vector<std::string> allExtensions;
115 std::set<wxString> allWildcardsSet;
116
117 for( const PLUGIN_FILE_DESC& desc : descriptions )
118 {
119 if( !fileFiltersStr.IsEmpty() )
120 fileFiltersStr += wxChar( '|' );
121
122 fileFiltersStr += desc.FileFilter();
123
124 for( const std::string& ext : desc.m_FileExtensions )
125 {
126 allExtensions.emplace_back( ext );
127 allWildcardsSet.insert( wxT( "*." ) + formatWildcardExt( ext ) + wxT( ";" ) );
128 }
129 }
130
131 wxString allWildcardsStr;
132
133 for( const wxString& wildcard : allWildcardsSet )
134 allWildcardsStr << wildcard;
135
136 if( aCtl & KICTL_KICAD_ONLY )
137 {
138 fileFiltersStr = _( "All KiCad Board Files" ) + AddFileExtListToFilter( allExtensions );
139 }
140 else
141 {
142 fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
143 + fileFiltersStr;
144 }
145
146 wxFileName fileName( *aFileName );
147 wxString path;
148 wxString name;
149
150 if( fileName.FileExists() )
151 {
152 path = fileName.GetPath();
153 name = fileName.GetFullName();
154 }
155 else
156 {
157 path = aParent->GetMruPath();
158
159 if( path.IsEmpty() )
161 // leave name empty
162 }
163
164 wxFileDialog dlg( aParent,
165 ( aCtl & KICTL_KICAD_ONLY ) ? _( "Open Board File" )
166 : _( "Import Non KiCad Board File" ),
167 path, name, fileFiltersStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
168
169 if( dlg.ShowModal() == wxID_OK )
170 {
171 *aFileName = dlg.GetPath();
172 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
173 return true;
174 }
175 else
176 {
177 return false;
178 }
179}
180
181
191bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
192{
193 wxString wildcard = PcbFileWildcard();
194 wxFileName fn = *aFileName;
195
196 fn.SetExt( KiCadPcbFileExtension );
197
198 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
199 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
200
201// Add a "Create a project" checkbox in standalone mode and one isn't loaded
202 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
203
204 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
205 dlg.SetCustomizeHook( newProjectHook );
206
207 if( dlg.ShowModal() != wxID_OK )
208 return false;
209
210 *aFileName = dlg.GetPath();
211 *aFileName = EnsureFileExtension( *aFileName, KiCadPcbFileExtension );
212
213 if( newProjectHook.IsAttachedToDialog() )
214 *aCreateProject = newProjectHook.GetCreateNewProject();
215 else if( !aParent->Prj().IsNullProject() )
216 *aCreateProject = true;
217
218 return true;
219}
220
221
222void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
223{
224 wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
225
226 if( !!fn )
227 {
228 if( !wxFileName::IsFileReadable( fn ) )
229 {
230 if( !AskLoadBoardFileName( this, &fn, KICTL_KICAD_ONLY ) )
231 return;
232 }
233
234 OpenProjectFiles( std::vector<wxString>( 1, fn ), KICTL_KICAD_ONLY );
235 }
236}
237
238
239void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
240{
242}
243
244
245void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
246{
247 int id = event.GetId();
248 Files_io_from_id( id );
249}
250
251
253{
254 wxString msg;
255
256 switch( id )
257 {
258 case ID_LOAD_FILE:
259 {
260 int open_ctl = KICTL_KICAD_ONLY;
261 wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
262
263 return AskLoadBoardFileName( this, &fileName, open_ctl )
264 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
265 }
266
268 {
269 int open_ctl = KICTL_NONKICAD_ONLY;
270 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
271
272 return AskLoadBoardFileName( this, &fileName, open_ctl )
273 && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
274 }
275
277 {
278 wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
279 wxFileName fn = currfn;
280
281 wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
282 fn.SetName( rec_name );
283
284 if( !fn.FileExists() )
285 {
286 msg.Printf( _( "Recovery file '%s' not found." ), fn.GetFullPath() );
287 DisplayInfoMessage( this, msg );
288 return false;
289 }
290
291 msg.Printf( _( "OK to load recovery file '%s'?" ), fn.GetFullPath() );
292
293 if( !IsOK( this, msg ) )
294 return false;
295
296 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
297
298 if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
299 {
300 // Re-set the name since name or extension was changed
301 GetBoard()->SetFileName( currfn.GetFullPath() );
302 UpdateTitle();
303 return true;
304 }
305
306 return false;
307 }
308
309 case ID_REVERT_BOARD:
310 {
311 wxFileName fn = Prj().AbsolutePath( GetBoard()->GetFileName() );
312
313 msg.Printf( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() );
314
315 if( !IsOK( this, msg ) )
316 return false;
317
318 GetScreen()->SetContentModified( false ); // do not prompt the user for changes
319
320 ReleaseFile();
321
322 return OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
323 }
324
325 case ID_NEW_BOARD:
326 {
327 if( IsContentModified() )
328 {
329 wxFileName fileName = GetBoard()->GetFileName();
330 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
331 "continuing?" );
332
333 if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
334 [&]()->bool
335 {
336 return Files_io_from_id( ID_SAVE_BOARD );
337 } ) )
338 {
339 return false;
340 }
341 }
342 else if( !GetBoard()->IsEmpty() )
343 {
344 if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
345 return false;
346 }
347
349
351
353 mgr->UnloadProject( &mgr->Prj() );
354
355 if( !Clear_Pcb( false ) )
356 return false;
357
359
361
362 OnModify();
363 return true;
364 }
365
366 case ID_SAVE_BOARD:
367 if( !GetBoard()->GetFileName().IsEmpty() )
368 {
369 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
370 {
371 m_autoSaveRequired = false;
372 return true;
373 }
374
375 return false;
376 }
377
379
380 case ID_COPY_BOARD_AS:
381 case ID_SAVE_BOARD_AS:
382 {
383 bool addToHistory = ( id == ID_SAVE_BOARD_AS );
384 wxString orig_name;
385
386 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
387
388 if( orig_name.IsEmpty() )
389 orig_name = NAMELESS_PROJECT;
390
391 wxFileName savePath( Prj().GetProjectFullName() );
392
393 if( !savePath.IsOk() || !savePath.IsDirWritable() )
394 {
395 savePath = GetMruPath();
396
397 if( !savePath.IsOk() || !savePath.IsDirWritable() )
399 }
400
401 wxFileName fn( savePath.GetPath(), orig_name, KiCadPcbFileExtension );
402 wxString filename = fn.GetFullPath();
403 bool createProject = false;
404 bool success = false;
405
406 if( AskSaveBoardFileName( this, &filename, &createProject ) )
407 {
408 if( id == ID_COPY_BOARD_AS )
409 {
410 success = SavePcbCopy( filename, createProject );
411 }
412 else
413 {
414 success = SavePcbFile( filename, addToHistory, createProject );
415
416 if( success )
417 m_autoSaveRequired = false;
418 }
419 }
420
421 return success;
422 }
423
424 default:
425 return false;
426 }
427}
428
429
431{
432 PCB_LAYER_COLLECTOR collector;
433
434 collector.SetLayerId( Edge_Cuts );
435 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
436
437 int edgeWidth = -1;
438 bool mixed = false;
439
440 for( int i = 0; i < collector.GetCount(); i++ )
441 {
442 if( collector[i]->Type() == PCB_SHAPE_T )
443 {
444 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
445
446 if( edgeWidth != -1 && edgeWidth != itemWidth )
447 {
448 mixed = true;
449 edgeWidth = std::max( edgeWidth, itemWidth );
450 }
451 else
452 {
453 edgeWidth = itemWidth;
454 }
455 }
456 }
457
458 if( mixed )
459 {
460 // If they had different widths then we can't ensure that fills will be the same.
461 DisplayInfoMessage( this, _( "If the zones on this board are refilled the Copper Edge Clearance "
462 "setting will be used (see Board Setup > Design Rules > Constraints).\n"
463 "This may result in different fills from previous KiCad versions which "
464 "used the line thicknesses of the board boundary on the Edge Cuts "
465 "layer." ) );
466 }
467
468 return std::max( 0, edgeWidth / 2 );
469}
470
471
472bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
473{
474 // This is for python:
475 if( aFileSet.size() != 1 )
476 {
477 UTF8 msg = StrPrintf( "Pcbnew:%s() takes a single filename", __func__ );
478 DisplayError( this, msg );
479 return false;
480 }
481
482 wxString fullFileName( aFileSet[0] );
483 wxFileName wx_filename( fullFileName );
484 wxString msg;
485
486 if( Kiface().IsSingle() )
488
489 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
490 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
491
492 std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
493
494 if( !lock->Valid() && lock->IsLockedByMe() )
495 {
496 // If we cannot acquire the lock but we appear to be the one who
497 // locked it, check to see if there is another KiCad instance running.
498 // If there is not, then we can override the lock. This could happen if
499 // KiCad crashed or was interrupted
500
501 if( !Pgm().SingleInstance()->IsAnotherRunning() )
502 lock->OverrideLock();
503 }
504
505 if( !lock->Valid() )
506 {
507 msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ), wx_filename.GetFullName(),
508 lock->GetUsername(), lock->GetHostname() );
509
510 if( !AskOverrideLock( this, msg ) )
511 return false;
512
513 lock->OverrideLock();
514 }
515
516 if( IsContentModified() )
517 {
518 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
519 [&]() -> bool
520 {
521 return SavePcbFile( GetBoard()->GetFileName() );
522 } ) )
523 {
524 return false;
525 }
526 }
527
528 wxFileName pro = fullFileName;
529 pro.SetExt( ProjectFileExtension );
530
531 bool is_new = !wxFileName::IsFileReadable( fullFileName );
532
533 // If its a non-existent schematic and caller thinks it exists
534 if( is_new && !( aCtl & KICTL_CREATE ) )
535 {
536 // notify user that fullFileName does not exist, ask if user wants to create it.
537 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
538
539 if( !IsOK( this, msg ) )
540 return false;
541 }
542
543 // Get rid of any existing warnings about the old board
544 GetInfoBar()->Dismiss();
545
546 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Creating PCB" )
547 : _( "Loading PCB" ), 1 );
548
549 // No save prompt (we already prompted above), and only reset to a new blank board if new
550 Clear_Pcb( false, !is_new );
551
552 IO_MGR::PCB_FILE_T pluginType = IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
553
554 if( pluginType == IO_MGR::FILE_TYPE_NONE )
555 return false;
556
557 bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
558
559 // Loading a project should only be done under carefully considered circumstances.
560
561 // The calling code should know not to ask me here to change projects unless
562 // it knows what consequences that will have on other KIFACEs running and using
563 // this same PROJECT. It can be very harmful if that calling code is stupid.
565
566 if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
567 {
568 // calls SaveProject
570
572 mgr->UnloadProject( &mgr->Prj() );
573
574 mgr->LoadProject( pro.GetFullPath() );
575
576 // Do not allow saving a project if one doesn't exist. This normally happens if we are
577 // standalone and opening a board that has been moved from its project folder.
578 // For converted projects, we don't want to set the read-only flag because we want a project
579 // to be saved for the new file in case things like netclasses got migrated.
580 Prj().SetReadOnly( !pro.Exists() && !converted );
581 }
582
583 // Clear the cache footprint list which may be project specific
585
586 if( is_new )
587 {
588 // Link the existing blank board to the new project
589 GetBoard()->SetProject( &Prj() );
590
591 GetBoard()->SetFileName( fullFileName );
592
593 OnModify();
594 }
595 else
596 {
597 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
598 PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
599
600 LAYER_REMAPPABLE_PLUGIN* layerRemappablePlugin =
601 dynamic_cast< LAYER_REMAPPABLE_PLUGIN* >( (PLUGIN*) pi );
602
603 if( layerRemappablePlugin )
604 {
605 layerRemappablePlugin->RegisterLayerMappingCallback(
606 std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, std::placeholders::_1 ) );
607 }
608
609 // This will rename the file if there is an autosave and the user want to recover
610 CheckForAutoSaveFile( fullFileName );
611
612 bool failedLoad = false;
613
614 try
615 {
616 if( pi == nullptr )
617 {
618 // There was no plugin found, e.g. due to invalid file extension, file header,...
619 THROW_IO_ERROR( _( "File format is not supported" ) );
620 }
621
622 STRING_UTF8_MAP props;
623
624 // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
625 props["page_width"] = std::to_string( GetPageSizeIU().x );
626 props["page_height"] = std::to_string( GetPageSizeIU().y );
627
629 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
630 {
631 KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
632
633 if( !aAction.IsEmpty() )
634 dlg.SetOKLabel( aAction );
635
636 dlg.DoNotShowCheckbox( aMessage, 0 );
637
638 return dlg.ShowModal() == wxID_OK;
639 } );
640
641#if USE_INSTRUMENTATION
642 // measure the time to load a BOARD.
643 unsigned startTime = GetRunningMicroSecs();
644#endif
645
646 loadedBoard = pi->LoadBoard( fullFileName, nullptr, &props, &Prj(), &progressReporter );
647
648#if USE_INSTRUMENTATION
649 unsigned stopTime = GetRunningMicroSecs();
650 printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
651#endif
652 }
653 catch( const FUTURE_FORMAT_ERROR& ffe )
654 {
655 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
656 progressReporter.Hide();
657 DisplayErrorMessage( this, msg, ffe.Problem() );
658
659 failedLoad = true;
660 }
661 catch( const IO_ERROR& ioe )
662 {
663 if( ioe.Problem() != wxT( "CANCEL" ) )
664 {
665 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
666 progressReporter.Hide();
667 DisplayErrorMessage( this, msg, ioe.What() );
668 }
669
670 failedLoad = true;
671 }
672 catch( const std::bad_alloc& )
673 {
674 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
675 progressReporter.Hide();
676 DisplayErrorMessage( this, msg, wxEmptyString );
677
678 failedLoad = true;
679 }
680
681 if( failedLoad || !loadedBoard )
682 {
683 // We didn't create a new blank board above, so do that now
684 Clear_Pcb( false );
685
686 return false;
687 }
688
689 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
690 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
691 // compiled.
692 Raise();
693
694 // Skip (possibly expensive) connectivity build here; we build it below after load
695 SetBoard( loadedBoard, false, &progressReporter );
696
697 if( GFootprintList.GetCount() == 0 )
698 GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
699
700 if( loadedBoard->m_LegacyDesignSettingsLoaded )
701 {
702 Prj().SetReadOnly( false );
703
704 // Before we had a copper edge clearance setting, the edge line widths could be used
705 // as a kludge to control them. So if there's no setting then infer it from the
706 // edge widths.
707 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
708 {
709 int edgeClearance = inferLegacyEdgeClearance( loadedBoard );
710 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
711 }
712
713 // On save; design settings will be removed from the board
714 loadedBoard->SetModified();
715 }
716
717 // Move legacy view settings to local project settings
718 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
719 {
721 loadedBoard->SetModified();
722 }
723
725 {
727 loadedBoard->SetModified();
728 }
729
730 // we should not ask PLUGINs to do these items:
731 loadedBoard->BuildListOfNets();
732 ResolveDRCExclusions( true );
734
735 if( loadedBoard->IsModified() )
736 OnModify();
737 else
738 GetScreen()->SetContentModified( false );
739
740 if( ( pluginType == IO_MGR::LEGACY )
741 || ( pluginType == IO_MGR::KICAD_SEXP
743 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
744 {
747 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
748 "It will be converted to the new format when saved." ),
750 }
751
752 // Import footprints into a project-specific library
753 //==================================================
754 // TODO: This should be refactored out of here into somewhere specific to the Project Import
755 // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
756 if( aCtl & KICTL_IMPORT_LIB )
757 {
758 wxFileName loadedBoardFn( fullFileName );
759 wxString libNickName = loadedBoardFn.GetName();
760
761 // Extract a footprint library from the design and add it to the fp-lib-table
762 // The footprints are saved in a new .pretty library.
763 // If this library already exists, all previous footprints will be deleted
764 std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
765 wxString newLibPath = CreateNewProjectLibrary( libNickName );
766
767 // Only create the new library if CreateNewLibrary succeeded (note that this fails if
768 // the library already exists and the user aborts after seeing the warning message
769 // which prompts the user to continue with overwrite or abort)
770 if( newLibPath.Length() > 0 )
771 {
773
774 for( FOOTPRINT* footprint : loadedFootprints )
775 {
776 try
777 {
778 if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
779 {
780 footprint->SetReference( "REF**" );
781 piSexpr->FootprintSave( newLibPath, footprint );
782 delete footprint;
783 }
784 }
785 catch( const IO_ERROR& ioe )
786 {
787 wxLogError( _( "Error saving footprint %s to project specific library." )
788 + wxS( "\n%s" ),
789 footprint->GetFPID().GetUniStringLibItemName(),
790 ioe.What() );
791 }
792 }
793
795 const wxString& project_env = PROJECT_VAR_NAME;
796 wxString rel_path, env_path;
797
798 wxASSERT_MSG( wxGetEnv( project_env, &env_path ),
799 wxT( "There is no project variable?" ) );
800
801 wxString result( newLibPath );
802
803 if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
804 rel_path = result;
805
806 FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
807 wxT( "KiCad" ), wxEmptyString );
808 prjlibtable->InsertRow( row );
809
810 wxString tblName = Prj().FootprintLibTblName();
811
812 try
813 {
814 PROJECT_PCB::PcbFootprintLibs( &Prj() )->Save( tblName );
815 }
816 catch( const IO_ERROR& ioe )
817 {
818 wxLogError( _( "Error saving project specific footprint library table." )
819 + wxS( "\n%s" ),
820 ioe.What() );
821 }
822
823 // Update footprint LIB_IDs to point to the just imported library
824 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
825 {
826 LIB_ID libId = footprint->GetFPID();
827
828 if( libId.GetLibItemName().empty() )
829 continue;
830
831 libId.SetLibNickname( libNickName );
832 footprint->SetFPID( libId );
833 }
834 }
835 }
836 }
837
838 {
839 wxFileName fn = fullFileName;
840
841 if( converted )
842 fn.SetExt( PcbFileExtension );
843
844 wxString fname = fn.GetFullPath();
845
846 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
847
848 GetBoard()->SetFileName( fname );
849 }
850
851 // Lock the file newly opened:
852 m_file_checker.reset( lock.release() );
853
854 if( !converted )
855 UpdateFileHistory( GetBoard()->GetFileName() );
856
857 std::vector<ZONE*> toFill;
858
859 // Rebuild list of nets (full ratsnest rebuild)
860 GetBoard()->BuildConnectivity( &progressReporter );
861
862 // Load project settings after setting up board; some of them depend on the nets list
864
865 // Syncs the UI (appearance panel, etc) with the loaded board and project
867
868 // Refresh the 3D view, if any
869 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
870
871 if( draw3DFrame )
872 draw3DFrame->NewDisplay();
873#if 0 && defined(DEBUG)
874 // Output the board object tree to stdout, but please run from command prompt:
875 GetBoard()->Show( 0, std::cout );
876#endif
877
878 // from EDA_APPL which was first loaded BOARD only:
879 {
880 /* For an obscure reason the focus is lost after loading a board file
881 * when starting up the process.
882 * (seems due to the recreation of the layer manager after loading the file)
883 * Give focus to main window and Drawpanel
884 * must be done for these 2 windows (for an obscure reason ...)
885 * Linux specific
886 * This is more a workaround than a fix.
887 */
888 SetFocus();
889 GetCanvas()->SetFocus();
890 }
891
892 return true;
893}
894
895
896bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
897 bool aChangeProject )
898{
899 // please, keep it simple. prompting goes elsewhere.
900 wxFileName pcbFileName = aFileName;
901
902 if( pcbFileName.GetExt() == LegacyPcbFileExtension )
903 pcbFileName.SetExt( KiCadPcbFileExtension );
904
905 // Write through symlinks, don't replace them
907
908 if( !IsWritable( pcbFileName ) )
909 {
910 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
911 pcbFileName.GetFullPath() );
912
913 DisplayError( this, msg );
914 return false;
915 }
916
917 // TODO: these will break if we ever go multi-board
918 wxFileName projectFile( pcbFileName );
919 wxFileName rulesFile( pcbFileName );
920 wxString msg;
921
922 projectFile.SetExt( ProjectFileExtension );
923 rulesFile.SetExt( DesignRulesFileExtension );
924
925 if( projectFile.FileExists() )
926 {
928 }
929 else if( aChangeProject )
930 {
931 Prj().SetReadOnly( false );
932 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
933 }
934
935 wxFileName currentRules( GetDesignRulesPath() );
936
937 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
938 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
939
940 if( !msg.IsEmpty() )
941 {
942 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
943 rulesFile.GetFullPath() ) );
944 }
945
946 if( projectFile.FileExists() )
947 {
948 // Save various DRC parameters, such as violation severities (which may have been
949 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
951
954 }
955
956 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew" ) );
957 wxString upperTxt;
958 wxString lowerTxt;
959
960 try
961 {
963
964 pi->SaveBoard( tempFile, GetBoard(), nullptr );
965 }
966 catch( const IO_ERROR& ioe )
967 {
968 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
969 pcbFileName.GetFullPath(),
970 ioe.What() ) );
971
972 lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile );
973
974 SetMsgPanel( upperTxt, lowerTxt );
975
976 // In case we started a file but didn't fully write it, clean up
977 wxRemoveFile( tempFile );
978
979 return false;
980 }
981
982 // Preserve the permissions of the current file
983 KIPLATFORM::IO::DuplicatePermissions( pcbFileName.GetFullPath(), tempFile );
984
985 // If save succeeded, replace the original with what we just wrote
986 if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
987 {
988 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n"
989 "Failed to rename temporary file '%s." ),
990 pcbFileName.GetFullPath(),
991 tempFile ) );
992
993 lowerTxt.Printf( _( "Failed to rename temporary file '%s'." ),
994 tempFile );
995
996 SetMsgPanel( upperTxt, lowerTxt );
997
998 return false;
999 }
1000
1001 if( !Kiface().IsSingle() )
1002 {
1003 WX_STRING_REPORTER backupReporter( &upperTxt );
1004
1005 if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1006 upperTxt.clear();
1007 }
1008
1009 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1010
1011 // Update the lock in case it was a Save As
1012 LockFile( pcbFileName.GetFullPath() );
1013
1014 // Put the saved file in File History if requested
1015 if( addToHistory )
1016 UpdateFileHistory( GetBoard()->GetFileName() );
1017
1018 // Delete auto save file on successful save.
1019 wxFileName autoSaveFileName = pcbFileName;
1020
1021 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
1022
1023 if( autoSaveFileName.FileExists() )
1024 wxRemoveFile( autoSaveFileName.GetFullPath() );
1025
1026 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1027
1028 SetStatusText( lowerTxt, 0 );
1029
1030 // Get rid of the old version conversion warning, or any other dismissable warning :)
1032 m_infoBar->Dismiss();
1033
1034 if( m_infoBar->IsShown() && m_infoBar->HasCloseButton() )
1035 m_infoBar->Dismiss();
1036
1037 GetScreen()->SetContentModified( false );
1038 UpdateTitle();
1039 return true;
1040}
1041
1042
1043bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
1044{
1045 wxFileName pcbFileName( EnsureFileExtension( aFileName, KiCadPcbFileExtension ) );
1046
1047 if( !IsWritable( pcbFileName ) )
1048 {
1049 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1050 pcbFileName.GetFullPath() ) );
1051 return false;
1052 }
1053
1054 // Save various DRC parameters, such as violation severities (which may have been
1055 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1057
1059
1060 try
1061 {
1063
1064 wxASSERT( pcbFileName.IsAbsolute() );
1065
1066 pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1067 }
1068 catch( const IO_ERROR& ioe )
1069 {
1070 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1071 pcbFileName.GetFullPath(),
1072 ioe.What() ) );
1073
1074 return false;
1075 }
1076
1077 wxFileName projectFile( pcbFileName );
1078 wxFileName rulesFile( pcbFileName );
1079 wxString msg;
1080
1081 projectFile.SetExt( ProjectFileExtension );
1082 rulesFile.SetExt( DesignRulesFileExtension );
1083
1084 if( aCreateProject && !projectFile.FileExists() )
1085 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1086
1087 wxFileName currentRules( GetDesignRulesPath() );
1088
1089 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1090 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1091
1092 if( !msg.IsEmpty() )
1093 {
1094 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1095 rulesFile.GetFullPath() ) );
1096 }
1097
1098 DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n%s" ),
1099 pcbFileName.GetFullPath() ) );
1100
1101 return true;
1102}
1103
1104
1106{
1107 wxFileName tmpFileName;
1108
1109 // Don't run autosave if content has not been modified
1110 if( !IsContentModified() )
1111 return true;
1112
1113 wxString title = GetTitle(); // Save frame title, that can be modified by the save process
1114
1115 if( GetBoard()->GetFileName().IsEmpty() )
1116 {
1117 tmpFileName = wxFileName( PATHS::GetDefaultUserProjectsPath(), NAMELESS_PROJECT,
1119 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1120 }
1121 else
1122 {
1123 tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1124 }
1125
1126 wxFileName autoSaveFileName = tmpFileName;
1127
1128 // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1129 autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
1130
1131 if( !autoSaveFileName.IsOk() )
1132 return false;
1133
1134 // If the board file path is not writable, try writing to a platform specific temp file
1135 // path. If that path isn't writable, give up.
1136 if( !autoSaveFileName.IsDirWritable() )
1137 {
1138 autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1139
1140 if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1141 return false;
1142 }
1143
1144 wxLogTrace( traceAutoSave,
1145 wxT( "Creating auto save file <" ) + autoSaveFileName.GetFullPath() + wxT( ">" ) );
1146
1147 if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1148 {
1150 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1151 UpdateTitle();
1152 m_autoSaveRequired = false;
1153 m_autoSavePending = false;
1154
1155 if( !Kiface().IsSingle() &&
1156 GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1157 {
1159 }
1160
1161 SetTitle( title ); // Restore initial frame title
1162
1163 return true;
1164 }
1165
1166 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1167
1168 SetTitle( title ); // Restore initial frame title
1169
1170 return false;
1171}
1172
1173
1174bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1175{
1176 switch( (IO_MGR::PCB_FILE_T) aFileType )
1177 {
1179 case IO_MGR::EAGLE:
1180 case IO_MGR::EASYEDA:
1181 case IO_MGR::EASYEDAPRO:
1182 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
1184
1185 default: break;
1186 }
1187
1188 return false;
1189}
1190
const char * name
Definition: DXF_plotter.cpp:57
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
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
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:271
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:351
GAL_SET m_LegacyVisibleItems
Definition: board.h:348
void BuildListOfNets()
Definition: board.h:782
void SetFileName(const wxString &aFileName)
Definition: board.h:306
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:168
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1630
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: board.h:347
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:178
const wxString & GetFileName() const
Definition: board.h:308
int GetFileFormatVersionAtLoad() const
Definition: board.h:372
const wxString & GetGenerator() const
Adds an item to the container.
Definition: board.h:375
void ClearProject()
Definition: board.cpp:217
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:731
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1621
bool m_LegacyCopperEdgeClearanceLoaded
Definition: board.h:352
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...
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.
std::unique_ptr< LOCKFILE > m_file_checker
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.
void SetFocus() override
void SetModified()
Definition: eda_item.cpp:64
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 PLUGIN_REGISTRY * Instance()
Definition: io_mgr.h:89
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:56
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:55
@ EASYEDA
Definition: io_mgr.h:62
@ EAGLE
Definition: io_mgr.h:61
@ FILE_TYPE_NONE
Definition: io_mgr.h:72
@ CADSTAR_PCB_ARCHIVE
Definition: io_mgr.h:60
@ EASYEDAPRO
Definition: io_mgr.h:63
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
Definition: io_mgr.cpp:116
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:63
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:47
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.
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:99
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:119
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:520
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)
const VECTOR2I GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
The main frame for Pcbnew.
void ResolveDRCExclusions(bool aCreateMarkers)
If aCreateMarkers then create DRC exclusion markers from the serialized data.
void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
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 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.
void SaveProjectLocalSettings() override
Save changes to the project local settings.
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...
bool Clear_Pcb(bool doAskAboutUnsavedChanges, bool aFinal=false)
Delete all and reinitialize the current board.
Definition: initpcb.cpp:40
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 saveProjectSettings() override
Saves any design-related project settings associated with this frame.
void OnFileHistory(wxCommandEvent &event)
Collect all BOARD_ITEM objects on a given layer.
Definition: collectors.h:545
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Test a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:525
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition: collectors.h:551
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:610
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:313
virtual PLUGIN_FILE_DESC GetBoardFileDesc() const
Returns board file description for the PLUGIN.
Definition: plugin.cpp:43
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:225
virtual std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints()
Return a container with the cached library footprints generated in the last call to Load.
Definition: plugin.cpp:152
virtual void SaveBoard(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:158
virtual BOARD * LoadBoard(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:144
LSET m_VisibleLayers
Board settings.
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
static FP_LIB_TABLE * PcbFootprintLibs(PROJECT *aProject)
Return the table of footprint libraries without Kiway.
Definition: project_pcb.cpp:37
virtual void SetReadOnly(bool aReadOnly=true)
Definition: project.h:144
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:137
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:172
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:173
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:328
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:161
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:165
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
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:301
bool HasCloseButton() const
Definition: wx_infobar.cpp:325
@ 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:187
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:291
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:154
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
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
Definition: common.cpp:398
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
Definition: confirm.cpp:155
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:332
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:305
This file is part of the common library.
#define _(s)
Declaration of the eda_3d_viewer class.
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:276
#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 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 THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
PROJECT & Prj()
Definition: kicad.cpp:571
#define KICTL_CREATE
caller thinks requested project files may not exist.
Definition: kiway_player.h:77
#define KICTL_IMPORT_LIB
import all footprints into a project library.
Definition: kiway_player.h:78
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
Definition: kiway_player.h:76
#define KICTL_NONKICAD_ONLY
chosen file is non-KiCad according to user
Definition: kiway_player.h:75
@ 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:227
@ Edge_Cuts
Definition: layer_ids.h:114
@ Rescue
Definition: layer_ids.h:134
#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:265
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
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:65
bool DuplicatePermissions(const wxString &aSrc, const wxString &aDest)
Duplicates the file security data from one file to another ensuring that they are the same between bo...
Definition: gtk/io.cpp:39
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
Definition: pcb_plugin.h:143
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
@ 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
SETTINGS_MANAGER * GetSettingsManager()
see class PGM_BASE
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
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:85
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:175
Container that describes file type info.
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
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.