KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/files.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2023 CERN (www.cern.ch)
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <string>
28
29#include <confirm.h>
30#include <kidialog.h>
31#include <core/arraydim.h>
32#include <thread_pool.h>
34#include <gestfich.h>
35#include <pcb_edit_frame.h>
38#include <fp_lib_table.h>
39#include <kiface_base.h>
40#include <macros.h>
41#include <trace_helpers.h>
43#include <lockfile.h>
44#include <wx/snglinst.h>
46#include <pcbnew_id.h>
48#include <tool/tool_manager.h>
49#include <board.h>
50#include <kiplatform/app.h>
52#include <widgets/wx_infobar.h>
55#include <paths.h>
56#include <pgm_base.h>
58#include <project_pcb.h>
62#include <pcb_io/pcb_io_mgr.h>
70#include <tools/pcb_actions.h>
72#include "footprint_info_impl.h"
73#include <board_commit.h>
74#include <zone_filler.h>
77#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
78#include <kiplatform/io.h>
79
80#include <wx/stdpaths.h>
81#include <wx/ffile.h>
82#include <wx/filedlg.h>
83#include <wx/txtstrm.h>
84#include <wx/wfstream.h>
85#include <wx/zipstrm.h>
86#include <wx/dir.h>
87
89
90//#define USE_INSTRUMENTATION 1
91#define USE_INSTRUMENTATION 0
92
93
103bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 )
104{
105 std::vector<IO_BASE::IO_FILE_DESC> descriptions;
106
107 for( const auto& plugin : PCB_IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins() )
108 {
109 bool isKiCad = plugin.m_type == PCB_IO_MGR::KICAD_SEXP || plugin.m_type == PCB_IO_MGR::LEGACY;
110
111 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
112 continue;
113
114 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
115 continue;
116
117 IO_RELEASER<PCB_IO> pi( plugin.m_createFunc() );
118 wxCHECK( pi, false );
119
120 const IO_BASE::IO_FILE_DESC& desc = pi->GetBoardFileDesc();
121
122 if( desc.m_FileExtensions.empty() || !desc.m_CanRead )
123 continue;
124
125 descriptions.emplace_back( desc );
126 }
127
128 wxString fileFiltersStr;
129 std::vector<std::string> allExtensions;
130 std::set<wxString> allWildcardsSet;
131
132 for( const IO_BASE::IO_FILE_DESC& desc : descriptions )
133 {
134 if( !fileFiltersStr.IsEmpty() )
135 fileFiltersStr += wxChar( '|' );
136
137 fileFiltersStr += desc.FileFilter();
138
139 for( const std::string& ext : desc.m_FileExtensions )
140 {
141 allExtensions.emplace_back( ext );
142 allWildcardsSet.insert( wxT( "*." ) + formatWildcardExt( ext ) + wxT( ";" ) );
143 }
144 }
145
146 wxString allWildcardsStr;
147
148 for( const wxString& wildcard : allWildcardsSet )
149 allWildcardsStr << wildcard;
150
151 if( aCtl & KICTL_KICAD_ONLY )
152 {
153 fileFiltersStr = _( "All KiCad Board Files" ) + AddFileExtListToFilter( allExtensions );
154 }
155 else
156 {
157 fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
158 + fileFiltersStr;
159 }
160
161 wxFileName fileName( *aFileName );
162 wxString path;
163 wxString name;
164
165 if( fileName.FileExists() )
166 {
167 path = fileName.GetPath();
168 name = fileName.GetFullName();
169 }
170 else
171 {
172 path = aParent->GetMruPath();
173
174 if( path.IsEmpty() )
176 // leave name empty
177 }
178
179 bool kicadFormat = ( aCtl & KICTL_KICAD_ONLY );
180
181 wxFileDialog dlg( aParent, kicadFormat ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
182 path, name, fileFiltersStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
183
184 FILEDLG_IMPORT_NON_KICAD importOptions( aParent->config()->m_System.show_import_issues );
185
186 if( !kicadFormat )
187 dlg.SetCustomizeHook( importOptions );
188
189 if( dlg.ShowModal() == wxID_OK )
190 {
191 *aFileName = dlg.GetPath();
192 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
193
194 if( !kicadFormat )
195 aParent->config()->m_System.show_import_issues = importOptions.GetShowIssues();
196
197 return true;
198 }
199 else
200 {
201 return false;
202 }
203}
204
205
215bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
216{
217 wxString wildcard = FILEEXT::PcbFileWildcard();
218 wxFileName fn = *aFileName;
219
221
222 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
223 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
224
225// Add a "Create a project" checkbox in standalone mode and one isn't loaded
226 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
227
228 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
229 dlg.SetCustomizeHook( newProjectHook );
230
231 if( dlg.ShowModal() != wxID_OK )
232 return false;
233
234 *aFileName = dlg.GetPath();
235 *aFileName = EnsureFileExtension( *aFileName, FILEEXT::KiCadPcbFileExtension );
236
237 if( newProjectHook.IsAttachedToDialog() )
238 *aCreateProject = newProjectHook.GetCreateNewProject();
239 else if( !aParent->Prj().IsNullProject() )
240 *aCreateProject = true;
241
242 return true;
243}
244
245
246void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
247{
248 wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
249
250 if( !!fn )
251 {
252 if( !wxFileName::IsFileReadable( fn ) )
253 {
254 if( !AskLoadBoardFileName( this, &fn, KICTL_KICAD_ONLY ) )
255 return;
256 }
257
258 OpenProjectFiles( std::vector<wxString>( 1, fn ), KICTL_KICAD_ONLY );
259 }
260}
261
262
263void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
264{
266}
267
268
270{
271 // Only standalone mode can directly load a new document
272 if( !Kiface().IsSingle() )
273 return false;
274
275 int open_ctl = KICTL_KICAD_ONLY;
276 wxString fileName = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
277
278 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
279 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
280
281 return 0;
282}
283
284
286{
287 // Note: we explicitly allow this even if not in standalone mode for now, even though it is dangerous.
288 int open_ctl = KICTL_NONKICAD_ONLY;
289 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
290
291 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
292 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
293
294 return 0;
295}
296
297
299{
300 wxFileName currfn = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
301 wxFileName fn = currfn;
302
303 wxString rec_name = FILEEXT::AutoSaveFilePrefix + fn.GetName();
304 fn.SetName( rec_name );
305
306 if( !fn.FileExists() )
307 {
308 DisplayError( m_frame, wxString::Format( _( "Recovery file '%s' not found." ), fn.GetFullPath() ) );
309 return 0;
310 }
311
312 if( !IsOK( m_frame, wxString::Format( _( "OK to load recovery file '%s'?" ), fn.GetFullPath() ) ) )
313 return false;
314
315 m_frame->GetScreen()->SetContentModified( false ); // do not prompt the user for changes
316
317 if( m_frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
318 {
319 // Re-set the name since name or extension was changed
320 m_frame->GetBoard()->SetFileName( currfn.GetFullPath() );
321 m_frame->UpdateTitle();
322 }
323
324 return 0;
325}
326
327
329{
330 wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
331
332 if( !IsOK( m_frame, wxString::Format( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() ) ) )
333 return false;
334
335 m_frame->GetScreen()->SetContentModified( false ); // do not prompt the user for changes
336
337 m_frame->ReleaseFile();
338
339 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ), KICTL_REVERT );
340
341 return 0;
342}
343
344
346{
347 // Only standalone mode can directly load a new document
348 if( !Kiface().IsSingle() )
349 return false;
350
351 if( m_frame->IsContentModified() )
352 {
353 wxFileName fileName = m_frame->GetBoard()->GetFileName();
354 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
355 "continuing?" );
356
357 if( !HandleUnsavedChanges( m_frame, wxString::Format( saveMsg, fileName.GetFullName() ),
358 [&]()->bool
359 {
360 return m_frame->SaveBoard();
361 } ) )
362 {
363 return false;
364 }
365 }
366 else if( !m_frame->GetBoard()->IsEmpty() )
367 {
368 if( !IsOK( m_frame, _( "Current Board will be closed. Continue?" ) ) )
369 return false;
370 }
371
372 m_frame->SaveProjectLocalSettings();
373
374 m_frame->GetBoard()->ClearProject();
375 m_frame->GetSettingsManager()->UnloadProject( &m_frame->Prj() );
376
377 if( !m_frame->Clear_Pcb( false ) )
378 return false;
379
380 m_frame->LoadProjectSettings();
381 m_frame->LoadDrawingSheet();
382
383 m_frame->OnBoardLoaded();
384 m_frame->OnModify();
385
386 return 0;
387}
388
389
390bool PCB_EDIT_FRAME::SaveBoard( bool aSaveAs, bool aSaveCopy )
391{
392 if( !aSaveAs )
393 {
394 if( !GetBoard()->GetFileName().IsEmpty() )
395 {
396 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
397 {
398 m_autoSaveRequired = false;
399 return true;
400 }
401
402 return false;
403 }
404 }
405
406 wxString orig_name;
407
408 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
409
410 if( orig_name.IsEmpty() )
411 orig_name = NAMELESS_PROJECT;
412
413 wxFileName savePath( Prj().GetProjectFullName() );
414
415 if( !savePath.IsOk() || !savePath.IsDirWritable() )
416 {
417 savePath = GetMruPath();
418
419 if( !savePath.IsOk() || !savePath.IsDirWritable() )
421 }
422
423 wxFileName fn( savePath.GetPath(), orig_name, FILEEXT::KiCadPcbFileExtension );
424 wxString filename = fn.GetFullPath();
425 bool createProject = false;
426 bool success = false;
427
428 if( AskSaveBoardFileName( this, &filename, &createProject ) )
429 {
430 if( aSaveCopy )
431 {
432 success = SavePcbCopy( EnsureFileExtension( filename, FILEEXT::KiCadPcbFileExtension ), createProject );
433 }
434 else
435 {
436 success = SavePcbFile( filename, aSaveAs, createProject );
437
438 if( success )
439 m_autoSaveRequired = false;
440 }
441 }
442
443 return success;
444}
445
446
447int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard, bool aShowUserMsg )
448{
449 PCB_LAYER_COLLECTOR collector;
450
451 collector.SetLayerId( Edge_Cuts );
452 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
453
454 int edgeWidth = -1;
455 bool mixed = false;
456
457 for( int i = 0; i < collector.GetCount(); i++ )
458 {
459 if( collector[i]->Type() == PCB_SHAPE_T )
460 {
461 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
462
463 if( edgeWidth != -1 && edgeWidth != itemWidth )
464 {
465 mixed = true;
466 edgeWidth = std::max( edgeWidth, itemWidth );
467 }
468 else
469 {
470 edgeWidth = itemWidth;
471 }
472 }
473 }
474
475 if( mixed && aShowUserMsg )
476 {
477 // If they had different widths then we can't ensure that fills will be the same.
478 DisplayInfoMessage( this,
479 _( "If the zones on this board are refilled the Copper Edge "
480 "Clearance setting will be used (see Board Setup > Design "
481 "Rules > Constraints).\n This may result in different fills "
482 "from previous KiCad versions which used the line thicknesses "
483 "of the board boundary on the Edge Cuts layer." ) );
484 }
485
486 return std::max( 0, edgeWidth / 2 );
487}
488
489
490bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
491{
492 // This is for python:
493 if( aFileSet.size() != 1 )
494 {
495 UTF8 msg = StrPrintf( "Pcbnew:%s() takes a single filename", __func__ );
496 DisplayError( this, msg );
497 return false;
498 }
499
500 wxString fullFileName( aFileSet[0] );
501 wxFileName wx_filename( fullFileName );
502 wxString msg;
503
504 if( Kiface().IsSingle() )
506
507 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
508 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
509
510 std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
511
512 if( !lock->Valid() && lock->IsLockedByMe() )
513 {
514 // If we cannot acquire the lock but we appear to be the one who locked it, check to
515 // see if there is another KiCad instance running. If not, then we can override the
516 // lock. This could happen if KiCad crashed or was interrupted.
517
518 if( !Pgm().SingleInstance()->IsAnotherRunning() )
519 lock->OverrideLock();
520 }
521
522 if( !lock->Valid() )
523 {
524 msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ),
525 wx_filename.GetFullName(),
526 lock->GetUsername(),
527 lock->GetHostname() );
528
529 if( !AskOverrideLock( this, msg ) )
530 return false;
531
532 lock->OverrideLock();
533 }
534
535 if( IsContentModified() )
536 {
537 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
538 [&]() -> bool
539 {
540 return SavePcbFile( GetBoard()->GetFileName() );
541 } ) )
542 {
543 return false;
544 }
545 }
546
547 wxFileName pro = fullFileName;
548 pro.SetExt( FILEEXT::ProjectFileExtension );
549
550 bool is_new = !wxFileName::IsFileReadable( fullFileName );
551
552 wxString previousBoardFileName = GetBoard() ? GetBoard()->GetFileName() : wxString();
553
554 // If its a non-existent PCB and caller thinks it exists
555 if( is_new && !( aCtl & KICTL_CREATE ) )
556 {
557 // notify user that fullFileName does not exist, ask if user wants to create it.
558 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
559
560 if( !IsOK( this, msg ) )
561 return false;
562 }
563
564 // Get rid of any existing warnings about the old board
565 GetInfoBar()->Dismiss();
566
567 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Create PCB" ) : _( "Load PCB" ), 1,
568 PR_CAN_ABORT );
569
570 // No save prompt (we already prompted above), and only reset to a new blank board if new
571 Clear_Pcb( false, !is_new );
572
574
575 if( !is_new )
576 pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
577
578 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
579 {
580 progressReporter.Hide();
581 DisplayErrorMessage( this, _( "File format is not supported" ), wxEmptyString );
582 return false;
583 }
584
585 bool converted = pluginType != PCB_IO_MGR::LEGACY && pluginType != PCB_IO_MGR::KICAD_SEXP;
586
587 // Loading a project should only be done under carefully considered circumstances.
588
589 // The calling code should know not to ask me here to change projects unless
590 // it knows what consequences that will have on other KIFACEs running and using
591 // this same PROJECT. It can be very harmful if that calling code is stupid.
593 bool setProject;
594
595 if( Kiface().IsSingle() || !( aCtl & KICTL_NONKICAD_ONLY ) )
596 setProject = pro.GetFullPath() != mgr->Prj().GetProjectFullName();
597 else
598 setProject = Prj().GetProjectFullName().IsEmpty();
599
600 if( setProject )
601 {
602 // calls SaveProject
604
606 mgr->UnloadProject( &mgr->Prj() );
607
608 mgr->LoadProject( pro.GetFullPath() );
609
610 // Do not allow saving a project if one doesn't exist. This normally happens if we are
611 // opening a board that has been moved from its project folder.
612 // For converted projects, we don't want to set the read-only flag because we want a
613 // project to be saved for the new file in case things like netclasses got migrated.
614 Prj().SetReadOnly( !pro.Exists() && !converted );
615 }
616
617 // Clear the cache footprint list which may be project specific
618 GFootprintList.Clear();
619
620 if( is_new )
621 {
622 // Link the existing blank board to the new project
623 GetBoard()->SetProject( &Prj() );
624
625 GetBoard()->SetFileName( fullFileName );
626
627 OnModify();
628 }
629 else
630 {
631 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
633
634 if( LAYER_MAPPABLE_PLUGIN* mappable_pi = dynamic_cast<LAYER_MAPPABLE_PLUGIN*>( pi.get() ) )
635 {
636 mappable_pi->RegisterCallback( std::bind( DIALOG_MAP_LAYERS::RunModal,
637 this, std::placeholders::_1 ) );
638 }
639
640 if( PROJECT_CHOOSER_PLUGIN* chooser_pi = dynamic_cast<PROJECT_CHOOSER_PLUGIN*>( pi.get() ) )
641 {
642 chooser_pi->RegisterCallback( std::bind( DIALOG_IMPORT_CHOOSE_PROJECT::RunModal,
643 this,
644 std::placeholders::_1 ) );
645 }
646
647 if( ( aCtl & KICTL_REVERT ) )
648 {
649 DeleteAutoSaveFile( fullFileName );
650 }
651 else
652 {
653 // This will rename the file if there is an autosave and the user wants to recover
654 CheckForAutoSaveFile( fullFileName );
655 }
656
657 DIALOG_HTML_REPORTER errorReporter( this );
658 bool failedLoad = false;
659
660 try
661 {
662 if( pi == nullptr )
663 {
664 // There was no plugin found, e.g. due to invalid file extension, file header,...
665 THROW_IO_ERROR( _( "File format is not supported" ) );
666 }
667
668 std::map<std::string, UTF8> props;
669
671 props.insert( m_importProperties->begin(), m_importProperties->end() );
672
673 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
674 props["page_width"] = std::to_string( GetPageSizeIU().x );
675 props["page_height"] = std::to_string( GetPageSizeIU().y );
676
677 pi->SetQueryUserCallback(
678 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
679 {
680 KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
681
682 if( !aAction.IsEmpty() )
683 dlg.SetOKLabel( aAction );
684
685 dlg.DoNotShowCheckbox( aMessage, 0 );
686
687 return dlg.ShowModal() == wxID_OK;
688 } );
689
690#if USE_INSTRUMENTATION
691 // measure the time to load a BOARD.
692 int64_t startTime = GetRunningMicroSecs();
693#endif
694 if( config()->m_System.show_import_issues )
695 pi->SetReporter( errorReporter.m_Reporter );
696 else
697 pi->SetReporter( &NULL_REPORTER::GetInstance() );
698
699 pi->SetProgressReporter( &progressReporter );
700 loadedBoard = pi->LoadBoard( fullFileName, nullptr, &props, &Prj() );
701
702#if USE_INSTRUMENTATION
703 int64_t stopTime = GetRunningMicroSecs();
704 printf( "PCB_IO::Load(): %u usecs\n", stopTime - startTime );
705#endif
706 }
707 catch( const FUTURE_FORMAT_ERROR& ffe )
708 {
709 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
710 progressReporter.Hide();
711 DisplayErrorMessage( this, msg, ffe.Problem() );
712
713 failedLoad = true;
714 }
715 catch( const IO_ERROR& ioe )
716 {
717 if( ioe.Problem() != wxT( "CANCEL" ) )
718 {
719 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
720 progressReporter.Hide();
721 DisplayErrorMessage( this, msg, ioe.What() );
722 }
723
724 failedLoad = true;
725 }
726 catch( const std::bad_alloc& )
727 {
728 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
729 progressReporter.Hide();
730 DisplayErrorMessage( this, msg, wxEmptyString );
731
732 failedLoad = true;
733 }
734
735 if( failedLoad || !loadedBoard )
736 {
737 // We didn't create a new blank board above, so do that now
738 Clear_Pcb( false );
739
740 return false;
741 }
742
743 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
744 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
745 // compiled.
746 Raise();
747
748 if( errorReporter.m_Reporter->HasMessage() )
749 {
750 errorReporter.m_Reporter->Flush(); // Build HTML messages
751 errorReporter.ShowModal();
752 }
753
754 // Skip (possibly expensive) connectivity build here; we build it below after load
755 SetBoard( loadedBoard, false, &progressReporter );
756
757 if( GFootprintList.GetCount() == 0 )
758 GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
759
760 if( loadedBoard->m_LegacyDesignSettingsLoaded )
761 {
762 Prj().SetReadOnly( false );
763
764 // Before we had a copper edge clearance setting, the edge line widths could be used
765 // as a kludge to control them. So if there's no setting then infer it from the
766 // edge widths.
767 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
768 {
769 // Do not show the inferred edge clearance warning dialog when loading third
770 // party boards. For some reason the dialog completely hangs all of KiCad and
771 // the imported board cannot be saved.
772 int edgeClearance = inferLegacyEdgeClearance( loadedBoard, !converted );
773 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
774 }
775
776 // On save; design settings will be removed from the board
777 loadedBoard->SetModified();
778 }
779
780 // Move legacy view settings to local project settings
781 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
782 {
784 loadedBoard->SetModified();
785 }
786
788 {
790 loadedBoard->SetModified();
791 }
792
793 if( !loadedBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
794 {
795 m_infoBar->RemoveAllButtons();
796 m_infoBar->AddCloseButton();
797 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
798 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
799 }
800
801 // we should not ask PCB_IOs to do these items:
802 loadedBoard->BuildListOfNets();
803 m_toolManager->RunAction( PCB_ACTIONS::repairBoard, true);
805
806 if( loadedBoard->IsModified() )
807 OnModify();
808 else
809 GetScreen()->SetContentModified( false );
810
811 if( ( pluginType == PCB_IO_MGR::LEGACY )
812 || ( pluginType == PCB_IO_MGR::KICAD_SEXP
814 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
815 {
816 m_infoBar->RemoveAllButtons();
817 m_infoBar->AddCloseButton();
818 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
819 "It will be converted to the new format when saved." ),
821 }
822
823 // Import footprints into a project-specific library
824 //==================================================
825 // TODO: This should be refactored out of here into somewhere specific to the Project Import
826 // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
827 if( aCtl & KICTL_IMPORT_LIB )
828 {
829 wxFileName loadedBoardFn( fullFileName );
830 wxString libNickName = loadedBoardFn.GetName();
831
832 // Extract a footprint library from the design and add it to the fp-lib-table
833 // The footprints are saved in a new .pretty library.
834 // If this library already exists, all previous footprints will be deleted
835 std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
836 wxString newLibPath = CreateNewProjectLibrary( _( "New Footprint Library" ),
837 libNickName );
838
839 // Only create the new library if CreateNewLibrary succeeded (note that this fails if
840 // the library already exists and the user aborts after seeing the warning message
841 // which prompts the user to continue with overwrite or abort)
842 if( newLibPath.Length() > 0 )
843 {
845
846 for( FOOTPRINT* footprint : loadedFootprints )
847 {
848 try
849 {
850 if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
851 {
852 footprint->SetReference( "REF**" );
853 piSexpr->FootprintSave( newLibPath, footprint );
854 delete footprint;
855 }
856 }
857 catch( const IO_ERROR& ioe )
858 {
859 wxLogError( _( "Error saving footprint %s to project specific library." )
860 + wxS( "\n%s" ),
861 footprint->GetFPID().GetUniStringLibItemName(),
862 ioe.What() );
863 }
864 }
865
867 const wxString& project_env = PROJECT_VAR_NAME;
868 wxString rel_path, env_path;
869
870 wxASSERT_MSG( wxGetEnv( project_env, &env_path ),
871 wxT( "There is no project variable?" ) );
872
873 wxString result( newLibPath );
874
875 if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
876 rel_path = result;
877
878 FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
879 wxT( "KiCad" ), wxEmptyString );
880 prjlibtable->InsertRow( row );
881
882 wxString tblName = Prj().FootprintLibTblName();
883
884 try
885 {
886 PROJECT_PCB::PcbFootprintLibs( &Prj() )->Save( tblName );
887 }
888 catch( const IO_ERROR& ioe )
889 {
890 wxLogError( _( "Error saving project specific footprint library table." )
891 + wxS( "\n%s" ),
892 ioe.What() );
893 }
894
895 // Update footprint LIB_IDs to point to the just imported library
896 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
897 {
898 LIB_ID libId = footprint->GetFPID();
899
900 if( libId.GetLibItemName().empty() )
901 continue;
902
903 libId.SetLibNickname( libNickName );
904 footprint->SetFPID( libId );
905 }
906 }
907 }
908 }
909
910 {
911 wxString fname;
912
913 if( !previousBoardFileName.IsEmpty() && ( aCtl & KICTL_NONKICAD_ONLY ) && !setProject )
914 {
915 fname = previousBoardFileName;
916 }
917 else
918 {
919 wxFileName fn;
920
921 fn.SetPath( Prj().GetProjectPath() );
922 fn.SetName( Prj().GetProjectName() );
924
925 fname = fn.GetFullPath();
926
927 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
928 }
929
930 GetBoard()->SetFileName( fname );
931 }
932
933 // Lock the file newly opened:
934 m_file_checker.reset( lock.release() );
935
936 if( !converted )
937 UpdateFileHistory( GetBoard()->GetFileName() );
938
939 std::vector<ZONE*> toFill;
940
941 // Rebuild list of nets (full ratsnest rebuild)
942 GetBoard()->BuildConnectivity( &progressReporter );
943
944 // Load project settings after setting up board; some of them depend on the nets list
947
948 // Resolve DRC exclusions after project settings are loaded
949 ResolveDRCExclusions( true );
950
951 // Initialise caches used by component classes
953
954 // Initialise time domain tuning caches
956
957 // Syncs the UI (appearance panel, etc) with the loaded board and project
959
960 // Refresh the 3D view, if any
961 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
962
963 if( draw3DFrame )
964 draw3DFrame->NewDisplay();
965#if 0 && defined(DEBUG)
966 // Output the board object tree to stdout, but please run from command prompt:
967 GetBoard()->Show( 0, std::cout );
968#endif
969
970 // from EDA_APPL which was first loaded BOARD only:
971 {
972 /* For an obscure reason the focus is lost after loading a board file
973 * when starting up the process.
974 * (seems due to the recreation of the layer manager after loading the file)
975 * Give focus to main window and Drawpanel
976 * must be done for these 2 windows (for an obscure reason ...)
977 * Linux specific
978 * This is more a workaround than a fix.
979 */
980 SetFocus();
981 GetCanvas()->SetFocus();
982 }
983
984 return true;
985}
986
987
988bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
989 bool aChangeProject )
990{
991 // please, keep it simple. prompting goes elsewhere.
992 wxFileName pcbFileName = aFileName;
993
994 if( pcbFileName.GetExt() == FILEEXT::LegacyPcbFileExtension )
995 pcbFileName.SetExt( FILEEXT::KiCadPcbFileExtension );
996
997 // Write through symlinks, don't replace them
999
1000 if( !IsWritable( pcbFileName ) )
1001 {
1002 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1003 pcbFileName.GetFullPath() );
1004
1005 DisplayError( this, msg );
1006 return false;
1007 }
1008
1009 // TODO: these will break if we ever go multi-board
1010 wxFileName projectFile( pcbFileName );
1011 wxFileName rulesFile( pcbFileName );
1012 wxString msg;
1013
1014 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1015 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1016
1017 if( projectFile.FileExists() )
1018 {
1020 }
1021 else if( aChangeProject )
1022 {
1023 Prj().SetReadOnly( false );
1024 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1025 }
1026
1027 wxFileName currentRules( GetDesignRulesPath() );
1028
1029 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1030 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1031
1032 if( !msg.IsEmpty() )
1033 {
1034 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1035 rulesFile.GetFullPath() ) );
1036 }
1037
1038 if( projectFile.FileExists() )
1039 {
1040 // Save various DRC parameters, such as violation severities (which may have been
1041 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1043
1046 }
1047
1048 wxString upperTxt;
1049 wxString lowerTxt;
1050
1051 try
1052 {
1054
1055 pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1056 }
1057 catch( const IO_ERROR& ioe )
1058 {
1059 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1060 pcbFileName.GetFullPath(),
1061 ioe.What() ) );
1062 return false;
1063 }
1064
1065 if( !Kiface().IsSingle() )
1066 {
1067 WX_STRING_REPORTER backupReporter;
1068
1069 if( !GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1070 {
1071 upperTxt = backupReporter.GetMessages();
1072 SetStatusText( upperTxt, 1 );
1073 }
1074 }
1075
1076 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1077
1078 // Update the lock in case it was a Save As
1079 LockFile( pcbFileName.GetFullPath() );
1080
1081 // Put the saved file in File History if requested
1082 if( addToHistory )
1083 UpdateFileHistory( GetBoard()->GetFileName() );
1084
1085 // Delete auto save file on successful save.
1086 wxFileName autoSaveFileName = pcbFileName;
1087
1088 autoSaveFileName.SetName( FILEEXT::AutoSaveFilePrefix + pcbFileName.GetName() );
1089
1090 if( autoSaveFileName.FileExists() )
1091 wxRemoveFile( autoSaveFileName.GetFullPath() );
1092
1093 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1094
1095 SetStatusText( lowerTxt, 0 );
1096
1097 // Get rid of the old version conversion warning, or any other dismissable warning :)
1098 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1099 m_infoBar->Dismiss();
1100
1101 if( m_infoBar->IsShownOnScreen() && m_infoBar->HasCloseButton() )
1102 m_infoBar->Dismiss();
1103
1104 GetScreen()->SetContentModified( false );
1105 UpdateTitle();
1107 return true;
1108}
1109
1110
1111bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
1112{
1113 wxFileName pcbFileName( aFileName );
1114
1115 if( !IsWritable( pcbFileName ) )
1116 {
1117 if( !aHeadless )
1118 {
1119 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1120 pcbFileName.GetFullPath() ) );
1121 }
1122 return false;
1123 }
1124
1125 // Save various DRC parameters, such as violation severities (which may have been
1126 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1128
1130
1131 try
1132 {
1134
1135 wxASSERT( pcbFileName.IsAbsolute() );
1136
1137 pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1138 }
1139 catch( const IO_ERROR& ioe )
1140 {
1141 if( !aHeadless )
1142 {
1143 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1144 pcbFileName.GetFullPath(),
1145 ioe.What() ) );
1146 }
1147
1148 return false;
1149 }
1150
1151 wxFileName projectFile( pcbFileName );
1152 wxFileName rulesFile( pcbFileName );
1153 wxString msg;
1154
1155 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1156 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1157
1158 if( aCreateProject && !projectFile.FileExists() )
1159 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1160
1161 wxFileName currentRules( GetDesignRulesPath() );
1162
1163 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1164 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1165
1166 if( !msg.IsEmpty() && !aHeadless )
1167 {
1168 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1169 rulesFile.GetFullPath() ) );
1170 }
1171
1172 return true;
1173}
1174
1175
1177{
1178 wxFileName tmpFileName;
1179
1180 // Don't run autosave if content has not been modified
1181 if( !IsContentModified() )
1182 return true;
1183
1184 wxString title = GetTitle(); // Save frame title, that can be modified by the save process
1185
1186 if( GetBoard()->GetFileName().IsEmpty() )
1187 {
1188 tmpFileName = wxFileName( PATHS::GetDefaultUserProjectsPath(), NAMELESS_PROJECT,
1190 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1191 }
1192 else
1193 {
1194 tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1195 }
1196
1197 wxFileName autoSaveFileName = tmpFileName;
1198
1199 // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1200 autoSaveFileName.SetName( FILEEXT::AutoSaveFilePrefix + autoSaveFileName.GetName() );
1201
1202 if( !autoSaveFileName.IsOk() )
1203 return false;
1204
1205 // If the board file path is not writable, try writing to a platform specific temp file
1206 // path. If that path isn't writable, give up.
1207 if( !autoSaveFileName.IsDirWritable() )
1208 {
1210 {
1211 DisplayError( this, wxString::Format(
1212 _( "Could not autosave files to read-only folder: '%s'" ),
1213 autoSaveFileName.GetPath() ) );
1215 }
1216
1217 autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1218
1219 if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1220 return false;
1221 }
1222
1223 if( !IsWritable( autoSaveFileName, false ) )
1224 {
1226 {
1227 DisplayError( this, wxString::Format(
1228 _( "Could not autosave files to read-only folder: '%s'" ),
1229 autoSaveFileName.GetPath() ) );
1231 }
1232
1233 return false;
1234 }
1235
1236 wxLogTrace( traceAutoSave,
1237 wxT( "Creating auto save file <" ) + autoSaveFileName.GetFullPath() + wxT( ">" ) );
1238
1239 if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1240 {
1242 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1243 UpdateTitle();
1244 m_autoSaveRequired = false;
1245 m_autoSavePending = false;
1246
1247 if( !Kiface().IsSingle() &&
1248 GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1249 {
1251 }
1252
1253 SetTitle( title ); // Restore initial frame title
1254
1255 return true;
1256 }
1257
1258 GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1259
1260 SetTitle( title ); // Restore initial frame title
1261
1262 return false;
1263}
1264
1265
1266bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
1267 const std::map<std::string, UTF8>* aProperties )
1268{
1269 NULLER raiiNuller( (void*&) m_importProperties );
1270
1271 m_importProperties = aProperties;
1272
1273 switch( (PCB_IO_MGR::PCB_FILE_T) aFileType )
1274 {
1276 case PCB_IO_MGR::EAGLE:
1279 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_NONKICAD_ONLY | KICTL_IMPORT_LIB );
1280
1285 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_NONKICAD_ONLY );
1286
1287 default:
1288 return false;
1289 }
1290}
1291
1292
1294{
1296
1297 dlg.ShowModal();
1298
1299 return 0;
1300}
1301
1302
1304{
1306
1307 if( dlg.ShowModal() != wxID_OK )
1308 return 0;
1309
1311
1313 job.m_filename = m_frame->GetBoard()->GetFileName();
1315
1316 job.m_precision = dlg.GetPrecision();
1319
1320 WX_PROGRESS_REPORTER progressReporter( m_frame, _( "Generate ODB++ Files" ), 3, PR_CAN_ABORT );
1321 WX_STRING_REPORTER reporter;
1322
1323 DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( job, m_frame->GetBoard(), m_frame, &progressReporter, &reporter );
1324
1325 if( reporter.HasMessage() )
1326 DisplayError( m_frame, reporter.GetMessages() );
1327
1328 return 0;
1329}
const char * name
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
void SetContentModified(bool aModified=true)
Definition base_screen.h:59
int RescueAutosave(const TOOL_EVENT &aEvent)
int GenerateODBPPFiles(const TOOL_EVENT &aEvent)
int New(const TOOL_EVENT &aEvent)
int Revert(const TOOL_EVENT &aEvent)
int GenIPC2581File(const TOOL_EVENT &aEvent)
int Open(const TOOL_EVENT &aEvent)
int OpenNonKicadBoard(const TOOL_EVENT &aEvent)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition board.h:411
GAL_SET m_LegacyVisibleItems
Definition board.h:408
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1359
void BuildListOfNets()
Definition board.h:916
void SetFileName(const wxString &aFileName)
Definition board.h:357
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:189
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2417
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition board.h:407
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:199
const wxString & GetFileName() const
Definition board.h:359
int GetFileFormatVersionAtLoad() const
Definition board.h:431
const wxString & GetGenerator() const
Adds an item to the container.
Definition board.h:434
void ClearProject()
Definition board.cpp:237
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1041
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:2404
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1364
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:2447
bool m_LegacyCopperEdgeClearanceLoaded
Definition board.h:412
int GetCount() const
Return the number of objects in the list.
Definition collector.h:83
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
static void GenerateODBPPFiles(const JOB_EXPORT_PCB_ODB &aJob, BOARD *aBoard, PCB_EDIT_FRAME *aParentFrame=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, REPORTER *aErrorReporter=nullptr)
wxString GetOutputPath() const
wxString GetUnitsString() const
Class DIALOG_HTML_REPORTER.
WX_HTML_REPORT_BOX * m_Reporter
static std::vector< IMPORT_PROJECT_DESC > RunModal(wxWindow *aParent, const std::vector< IMPORT_PROJECT_DESC > &aProjectDesc)
Create and show a dialog (modal) and returns the data from it after completion.
static std::map< wxString, PCB_LAYER_ID > RunModal(wxWindow *aParent, const std::vector< INPUT_LAYER_DESC > &aLayerDesc)
Create and show a dialog (modal) and returns the data from it after completion.
int ShowModal() override
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
bool m_autoSavePermissionError
WX_INFOBAR * m_infoBar
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxString GetMruPath() const
virtual void DeleteAutoSaveFile(const wxFileName &aFileName)
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
virtual void ClearFileHistory()
Remove all files from the file history.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
void SetMruPath(const wxString &aPath)
WX_INFOBAR * GetInfoBar()
std::unique_ptr< LOCKFILE > m_file_checker
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
void SetFocus() override
void SetModified()
Definition eda_item.cpp:100
bool IsModified() const
Definition eda_item.h:123
bool GetCreateNewProject() const
Gets the selected state of the copy subsheets option.
Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN object in t...
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
Definition collectors.h:41
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
ODB_COMPRESSION m_compressionMode
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
Definition job.cpp:153
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:42
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition kidialog.cpp:55
int ShowModal() override
Definition kidialog.cpp:93
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Plugin class for import plugins that support remappable layers.
void SynchronizeTimeDomainProperties() const
Ensure time domain properties provider is synced with board / project settings if required.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:100
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.
Definition raii.h:38
static REPORTER & GetInstance()
Definition reporter.cpp:96
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:136
static TOOL_ACTION repairBoard
static TOOL_ACTION rehatchShapes
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
wxString CreateNewProjectLibrary(const wxString &aDialogTitle, const wxString &aLibName)
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()
virtual void UpdateStatusBar() override
Update the status bar information.
The main frame for Pcbnew.
void LoadDrawingSheet()
Load the drawing sheet file.
void ResolveDRCExclusions(bool aCreateMarkers)
If aCreateMarkers then create DRC exclusion markers from the serialized data.
void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
void OnModify() override
Must be called after a board change to set the modified flag.
bool DoAutoSave()
Perform auto save when the board has been modified and not saved within the auto save interval.
void OnClearFileHistory(wxCommandEvent &aEvent)
bool SaveBoard(bool aSaveAs=false, bool aSaveCopy=false)
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
void SaveProjectLocalSettings() override
Save changes to the project local settings.
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false, bool aHeadless=false)
Write the board data structures to aFileName.
bool IsContentModified() const override
Get if the current board has been modified but not saved.
bool LoadProjectSettings()
Load the current project's file configuration settings which are pertinent to this PCB_EDIT_FRAME ins...
bool Clear_Pcb(bool doAskAboutUnsavedChanges, bool aFinal=false)
Delete all and reinitialize the current board.
Definition initpcb.cpp:42
void OnBoardLoaded()
Update the state of the GUI after a new board is loaded or created.
void UpdateTitle()
Set the main window title bar text.
int inferLegacyEdgeClearance(BOARD *aBoard, bool aShowUserMsg=true)
const std::map< std::string, UTF8 > * m_importProperties
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Write the board data structures to a aFileName.
bool importFile(const wxString &aFileName, int aFileType, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void saveProjectSettings() override
Save any design-related project settings associated with this frame.
void OnFileHistory(wxCommandEvent &event)
static PLUGIN_REGISTRY * Instance()
Definition pcb_io_mgr.h:94
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:56
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:58
@ ALTIUM_DESIGNER
Definition pcb_io_mgr.h:62
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition pcb_io_mgr.h:59
@ ALTIUM_CIRCUIT_MAKER
Definition pcb_io_mgr.h:60
@ ALTIUM_CIRCUIT_STUDIO
Definition pcb_io_mgr.h:61
@ CADSTAR_PCB_ARCHIVE
Definition pcb_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.
Collect all BOARD_ITEM objects on a given layer.
Definition collectors.h:549
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Test a BOARD_ITEM using this class's Inspector method, which does the collection.
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition collectors.h:555
Plugin class for import plugins that support choosing a project.
LSET m_VisibleLayers
Board settings.
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
static FP_LIB_TABLE * PcbFootprintLibs(PROJECT *aProject)
Return the table of footprint libraries without Kiway.
virtual void SetReadOnly(bool aReadOnly=true)
Definition project.h:168
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:156
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:210
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition project.cpp:192
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:386
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition project.cpp:180
virtual bool HasMessage() const
Returns true if any messages were reported.
Definition reporter.h:134
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save a copy of the current project under the given path.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Call BackupProject() if a new backup is needed according to the current backup policy.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
TOOL_MANAGER * m_toolManager
Generic, UI-independent tool event.
Definition tool_event.h:171
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:72
bool empty() const
Definition utf8.h:110
static void ResolvePossibleSymlinks(wxFileName &aFilename)
void Flush()
Build the HTML messages page.
bool HasMessage() const override
Returns true if any messages were reported.
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
Definition wx_infobar.h:96
@ GENERIC
GENERIC Are messages that do not have special handling.
Definition wx_infobar.h:95
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
A wrapper for reporting to a wxString object.
Definition reporter.h:191
const wxString & GetMessages() const
Definition reporter.cpp:77
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:429
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:42
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition confirm.cpp:251
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:222
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:129
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:194
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:169
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:156
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition gestfich.cpp:290
#define WIN_STRING_DIR_SEP
Definition gestfich.h:38
#define UNIX_STRING_DIR_SEP
Definition gestfich.h:37
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string AutoSaveFilePrefix
static const std::string DesignRulesFileExtension
static const std::string KiCadPcbFileExtension
static wxString PcbFileWildcard()
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PROJECT & Prj()
Definition kicad.cpp:612
#define KICTL_CREATE
caller thinks requested project files may not exist.
#define KICTL_REVERT
reverting to a previously-saved (KiCad) file.
#define KICTL_IMPORT_LIB
import all footprints into a project library.
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
#define KICTL_NONKICAD_ONLY
chosen file is non-KiCad according to user
@ GAL_LAYER_ID_BITMASK_END
This is the end of the layers used for visibility bit masks in legacy board files.
Definition layer_ids.h:287
@ Edge_Cuts
Definition layer_ids.h:112
@ Rescue
Definition layer_ids.h:121
#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:364
File locking utilities.
This file contains miscellaneous commonly used macros and functions.
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition unix/app.cpp:65
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:913
see class PGM_BASE
int64_t 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:40
#define NAMELESS_PROJECT
default name for nameless projects
Definition project.h:43
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:71
bool show_import_issues
Stored value for "show import issues" when importing non-KiCad designs to this application.
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Container that describes file type info.
Definition io_base.h:43
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
Definition io_base.h:47
bool m_CanRead
Whether the IO can read this file type.
Definition io_base.h:52
wxString result
Test unit parsing edge cases and error handling.
wxLogTrace helper definitions.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:88
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
Definition of file extensions used in Kicad.
#define PR_CAN_ABORT