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#include <vector>
29
30#include <advanced_config.h>
31#include <confirm.h>
32#include <kidialog.h>
33#include <core/arraydim.h>
34#include <core/profile.h>
35#include <thread_pool.h>
36#include <gestfich.h>
37#include <local_history.h>
38#include <pcb_edit_frame.h>
42#include <kiface_base.h>
43#include <macros.h>
44#include <trace_helpers.h>
46#include <lockfile.h>
47#include <wx/snglinst.h>
49#include <pcbnew_id.h>
51#include <tool/tool_manager.h>
52#include <board.h>
53#include <collectors.h>
55#include <kiplatform/app.h>
56#include <kiplatform/ui.h>
58#include <widgets/wx_infobar.h>
61#include <paths.h>
62#include <pgm_base.h>
64#include <project_pcb.h>
68#include <pcb_io/pcb_io_mgr.h>
76#include <tools/pcb_actions.h>
78#include <board_commit.h>
79#include <reporter.h>
80#include <zone_filler.h>
82#include <widgets/kistatusbar.h>
84#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
85#include <kiplatform/io.h>
86
87#include <wx/stdpaths.h>
88#include <wx/ffile.h>
89#include <wx/filedlg.h>
90#include <wx/txtstrm.h>
91#include <wx/wfstream.h>
92#include <wx/zipstrm.h>
93#include <wx/dir.h>
94
96
97//#define USE_INSTRUMENTATION 1
98#define USE_INSTRUMENTATION 0
99
100static const wxChar* const traceAllegroPerf = wxT( "KICAD_ALLEGRO_PERF" );
101
102
112bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 )
113{
114 std::vector<IO_BASE::IO_FILE_DESC> descriptions;
115
116 for( const auto& plugin : PCB_IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins() )
117 {
118 bool isKiCad = plugin.m_type == PCB_IO_MGR::KICAD_SEXP || plugin.m_type == PCB_IO_MGR::LEGACY;
119
120 if( ( aCtl & KICTL_KICAD_ONLY ) && !isKiCad )
121 continue;
122
123 if( ( aCtl & KICTL_NONKICAD_ONLY ) && isKiCad )
124 continue;
125
126 IO_RELEASER<PCB_IO> pi( plugin.m_createFunc() );
127 wxCHECK( pi, false );
128
129 const IO_BASE::IO_FILE_DESC& desc = pi->GetBoardFileDesc();
130
131 if( desc.m_FileExtensions.empty() || !desc.m_CanRead )
132 continue;
133
134 descriptions.emplace_back( desc );
135 }
136
137 wxString fileFiltersStr;
138 std::vector<std::string> allExtensions;
139 std::set<wxString> allWildcardsSet;
140
141 for( const IO_BASE::IO_FILE_DESC& desc : descriptions )
142 {
143 if( !fileFiltersStr.IsEmpty() )
144 fileFiltersStr += wxChar( '|' );
145
146 fileFiltersStr += desc.FileFilter();
147
148 for( const std::string& ext : desc.m_FileExtensions )
149 {
150 allExtensions.emplace_back( ext );
151 allWildcardsSet.insert( wxT( "*." ) + formatWildcardExt( ext ) + wxT( ";" ) );
152 }
153 }
154
155 wxString allWildcardsStr;
156
157 for( const wxString& wildcard : allWildcardsSet )
158 allWildcardsStr << wildcard;
159
160 if( aCtl & KICTL_KICAD_ONLY )
161 {
162 fileFiltersStr = _( "All KiCad Board Files" ) + AddFileExtListToFilter( allExtensions );
163 }
164 else
165 {
166 fileFiltersStr = _( "All supported formats" ) + wxT( "|" ) + allWildcardsStr + wxT( "|" )
167 + fileFiltersStr;
168 }
169
170 wxFileName fileName( *aFileName );
171 wxString path;
172 wxString name;
173
174 if( fileName.FileExists() )
175 {
176 path = fileName.GetPath();
177 name = fileName.GetFullName();
178 }
179 else
180 {
181 path = aParent->GetMruPath();
182
183 if( path.IsEmpty() )
185 // leave name empty
186 }
187
188 bool kicadFormat = ( aCtl & KICTL_KICAD_ONLY );
189
190 wxFileDialog dlg( aParent, kicadFormat ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
191 path, name, fileFiltersStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
192
193 FILEDLG_IMPORT_NON_KICAD importOptions( aParent->config()->m_System.show_import_issues );
194
195 if( !kicadFormat )
196 dlg.SetCustomizeHook( importOptions );
197
199
200 if( dlg.ShowModal() == wxID_OK )
201 {
202 *aFileName = dlg.GetPath();
203 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
204
205 if( !kicadFormat )
206 aParent->config()->m_System.show_import_issues = importOptions.GetShowIssues();
207
208 return true;
209 }
210 else
211 {
212 return false;
213 }
214}
215
216
226bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
227{
228 wxString wildcard = FILEEXT::PcbFileWildcard();
229 wxFileName fn = *aFileName;
230
232
233 wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
234 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
235
236// Add a "Create a project" checkbox in standalone mode and one isn't loaded
237 FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
238
239 if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
240 dlg.SetCustomizeHook( newProjectHook );
241
243
244 if( dlg.ShowModal() != wxID_OK )
245 return false;
246
247 *aFileName = dlg.GetPath();
248 *aFileName = EnsureFileExtension( *aFileName, FILEEXT::KiCadPcbFileExtension );
249
250 if( newProjectHook.IsAttachedToDialog() )
251 *aCreateProject = newProjectHook.GetCreateNewProject();
252 else if( !aParent->Prj().IsNullProject() )
253 *aCreateProject = true;
254
255 return true;
256}
257
258
259void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
260{
261 wxString filename = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
262
263 if( !filename.IsEmpty() )
264 {
265 if( !wxFileName::IsFileReadable( filename ) )
266 {
267 if( !AskLoadBoardFileName( this, &filename, KICTL_KICAD_ONLY ) )
268 return;
269 }
270
271 OpenProjectFiles( std::vector<wxString>( 1, filename ), KICTL_KICAD_ONLY );
272 }
273}
274
275
276void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
277{
279}
280
281
283{
284 // Only standalone mode can directly load a new document
285 if( !Kiface().IsSingle() )
286 return false;
287
288 int open_ctl = KICTL_KICAD_ONLY;
289 wxString fileName = m_frame->Prj().AbsolutePath( m_frame->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 // Note: we explicitly allow this even if not in standalone mode for now, even though it is dangerous.
301 int open_ctl = KICTL_NONKICAD_ONLY;
302 wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
303
304 if( AskLoadBoardFileName( m_frame, &fileName, open_ctl ) )
305 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
306
307 return 0;
308}
309
310
312{
313 wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->GetBoard()->GetFileName() );
314
315 if( !IsOK( m_frame, wxString::Format( _( "Revert '%s' to last version saved?" ), fn.GetFullPath() ) ) )
316 return false;
317
318 m_frame->GetScreen()->SetContentModified( false ); // do not prompt the user for changes
319
320 m_frame->ReleaseFile();
321
322 m_frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ), KICTL_REVERT );
323
324 return 0;
325}
326
327
329{
330 // Only standalone mode can directly load a new document
331 if( !Kiface().IsSingle() )
332 return false;
333
334 if( m_frame->IsContentModified() )
335 {
336 wxFileName fileName = m_frame->GetBoard()->GetFileName();
337 wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
338 "continuing?" );
339
340 if( !HandleUnsavedChanges( m_frame, wxString::Format( saveMsg, fileName.GetFullName() ),
341 [&]()->bool
342 {
343 return m_frame->SaveBoard();
344 } ) )
345 {
346 return false;
347 }
348 }
349 else if( !m_frame->GetBoard()->IsEmpty() )
350 {
351 if( !IsOK( m_frame, _( "Current Board will be closed. Continue?" ) ) )
352 return false;
353 }
354
355 m_frame->SaveProjectLocalSettings();
356
357 m_frame->GetBoard()->ClearProject();
358 m_frame->GetSettingsManager()->UnloadProject( &m_frame->Prj() );
359
360 if( !m_frame->Clear_Pcb( false ) )
361 return false;
362
363 m_frame->LoadProjectSettings();
364 m_frame->LoadDrawingSheet();
365
366 m_frame->OnBoardLoaded();
367 m_frame->OnModify();
368
369 return 0;
370}
371
372
373bool PCB_EDIT_FRAME::SaveBoard( bool aSaveAs, bool aSaveCopy )
374{
375 if( !aSaveAs )
376 {
377 if( !GetBoard()->GetFileName().IsEmpty() )
378 {
379 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
380 {
381 m_autoSaveRequired = false;
382 return true;
383 }
384
385 return false;
386 }
387 }
388
389 wxString orig_name;
390
391 wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
392
393 if( orig_name.IsEmpty() )
394 orig_name = NAMELESS_PROJECT;
395
396 wxFileName savePath( Prj().GetProjectFullName() );
397
398 if( !savePath.IsOk() || !savePath.IsDirWritable() )
399 {
400 savePath = GetMruPath();
401
402 if( !savePath.IsOk() || !savePath.IsDirWritable() )
404 }
405
406 wxFileName fn( savePath.GetPath(), orig_name, FILEEXT::KiCadPcbFileExtension );
407 wxString filename = fn.GetFullPath();
408 bool createProject = false;
409 bool success = false;
410
411 if( AskSaveBoardFileName( this, &filename, &createProject ) )
412 {
413 if( aSaveCopy )
414 {
415 success = SavePcbCopy( EnsureFileExtension( filename, FILEEXT::KiCadPcbFileExtension ), createProject );
416 }
417 else
418 {
419 success = SavePcbFile( filename, aSaveAs, createProject );
420
421 if( success )
422 m_autoSaveRequired = false;
423 }
424 }
425
426 return success;
427}
428
429
430int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard, bool aShowUserMsg )
431{
432 PCB_LAYER_COLLECTOR collector;
433
434 collector.SetLayerId( Edge_Cuts );
435 collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
436
437 int edgeWidth = -1;
438 bool mixed = false;
439
440 for( int i = 0; i < collector.GetCount(); i++ )
441 {
442 if( collector[i]->Type() == PCB_SHAPE_T )
443 {
444 int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
445
446 if( edgeWidth != -1 && edgeWidth != itemWidth )
447 {
448 mixed = true;
449 edgeWidth = std::max( edgeWidth, itemWidth );
450 }
451 else
452 {
453 edgeWidth = itemWidth;
454 }
455 }
456 }
457
458 if( mixed && aShowUserMsg )
459 {
460 // If they had different widths then we can't ensure that fills will be the same.
461 DisplayInfoMessage( this,
462 _( "If the zones on this board are refilled the Copper Edge "
463 "Clearance setting will be used (see Board Setup > Design "
464 "Rules > Constraints).\n This may result in different fills "
465 "from previous KiCad versions which used the line thicknesses "
466 "of the board boundary on the Edge Cuts layer." ) );
467 }
468
469 return std::max( 0, edgeWidth / 2 );
470}
471
472
473bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
474{
475 // This is for python:
476 if( aFileSet.size() != 1 )
477 {
478 DisplayError( this, wxString::Format( "Pcbnew:%s() takes a single filename", __func__ ) );
479 return false;
480 }
481
482 wxString fullFileName( aFileSet[0] );
483 wxFileName wx_filename( fullFileName );
484 Kiway().LocalHistory().Init( wx_filename.GetPath() );
485 wxString msg;
486
487 if( Kiface().IsSingle() )
489
490 // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
491 wxASSERT_MSG( wx_filename.IsAbsolute(), wxT( "Path is not absolute!" ) );
492
493 std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
494
495 if( !lock->Valid() && lock->IsLockedByMe() )
496 {
497 // If we cannot acquire the lock but we appear to be the one who locked it, check to
498 // see if there is another KiCad instance running. If not, then we can override the
499 // lock. This could happen if KiCad crashed or was interrupted.
500
501 if( !Pgm().SingleInstance()->IsAnotherRunning() )
502 lock->OverrideLock();
503 }
504
505 if( !lock->Valid() )
506 {
507 // If project-level lock override was already granted, silently override this file's lock
508 if( Prj().IsLockOverrideGranted() )
509 {
510 lock->OverrideLock();
511 }
512 else
513 {
514 msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ),
515 wx_filename.GetFullName(),
516 lock->GetUsername(),
517 lock->GetHostname() );
518
519 if( !AskOverrideLock( this, msg ) )
520 return false;
521
522 lock->OverrideLock();
523 }
524 }
525
526 if( IsContentModified() )
527 {
528 if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
529 [&]() -> bool
530 {
531 return SavePcbFile( GetBoard()->GetFileName() );
532 } ) )
533 {
534 return false;
535 }
536 }
537
538 wxFileName pro = fullFileName;
539 pro.SetExt( FILEEXT::ProjectFileExtension );
540
541 bool is_new = !wxFileName::IsFileReadable( fullFileName );
542
543 wxString previousBoardFileName = GetBoard() ? GetBoard()->GetFileName() : wxString();
544
545 // If its a non-existent PCB and caller thinks it exists
546 if( is_new && !( aCtl & KICTL_CREATE ) )
547 {
548 // notify user that fullFileName does not exist, ask if user wants to create it.
549 msg.Printf( _( "PCB '%s' does not exist. Do you wish to create it?" ), fullFileName );
550
551 if( !IsOK( this, msg ) )
552 return false;
553 }
554
555 // Get rid of any existing warnings about the old board
556 GetInfoBar()->Dismiss();
557
558 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
559 statusBar->ClearLoadWarningMessages();
560
561 WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Create PCB" ) : _( "Load PCB" ), 1,
562 PR_CAN_ABORT );
563 WX_STRING_REPORTER loadReporter;
564 LOAD_INFO_REPORTER_SCOPE loadReporterScope( &loadReporter );
565
566 // No save prompt (we already prompted above), and only reset to a new blank board if new
567 Clear_Pcb( false, !is_new );
568
570
571 if( !is_new )
572 pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( fullFileName, aCtl );
573
574 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
575 {
576 progressReporter.Hide();
577 DisplayErrorMessage( this, _( "File format is not supported" ), wxEmptyString );
578 return false;
579 }
580
581 bool converted = pluginType != PCB_IO_MGR::LEGACY && pluginType != PCB_IO_MGR::KICAD_SEXP;
582
583 // Loading a project should only be done under carefully considered circumstances.
584
585 // The calling code should know not to ask me here to change projects unless
586 // it knows what consequences that will have on other KIFACEs running and using
587 // this same PROJECT. It can be very harmful if that calling code is stupid.
589 bool setProject;
590
591 if( Kiface().IsSingle() || !( aCtl & KICTL_NONKICAD_ONLY ) )
592 setProject = pro.GetFullPath() != mgr->Prj().GetProjectFullName();
593 else
594 setProject = Prj().GetProjectFullName().IsEmpty();
595
596 if( setProject )
597 {
598 // calls SaveProject
600
602 mgr->UnloadProject( &mgr->Prj() );
603
604 mgr->LoadProject( pro.GetFullPath() );
605
606 // Do not allow saving a project if one doesn't exist. This normally happens if we are
607 // opening a board that has been moved from its project folder.
608 // For converted projects, we don't want to set the read-only flag because we want a
609 // project to be saved for the new file in case things like netclasses got migrated.
610 Prj().SetReadOnly( !pro.Exists() && !converted );
611 }
612
613 if( is_new )
614 {
615 // Link the existing blank board to the new project
616 GetBoard()->SetProject( &Prj() );
617
618 GetBoard()->SetFileName( fullFileName );
619
620 OnModify();
621 }
622 else
623 {
624 BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
626
627 if( LAYER_MAPPABLE_PLUGIN* mappable_pi = dynamic_cast<LAYER_MAPPABLE_PLUGIN*>( pi.get() ) )
628 {
629 if( !ADVANCED_CFG::GetCfg().m_ImportSkipLayerMapping )
630 {
631 mappable_pi->RegisterCallback( std::bind( DIALOG_MAP_LAYERS::RunModal,
632 this, std::placeholders::_1 ) );
633 }
634 }
635
636 if( PROJECT_CHOOSER_PLUGIN* chooser_pi = dynamic_cast<PROJECT_CHOOSER_PLUGIN*>( pi.get() ) )
637 {
638 chooser_pi->RegisterCallback( std::bind( DIALOG_IMPORT_CHOOSE_PROJECT::RunModal,
639 this,
640 std::placeholders::_1 ) );
641 }
642
643 bool failedLoad = false;
644
645 try
646 {
647 if( pi == nullptr )
648 {
649 // There was no plugin found, e.g. due to invalid file extension, file header,...
650 THROW_IO_ERROR( _( "File format is not supported" ) );
651 }
652
653 std::map<std::string, UTF8> props;
654
656 props.insert( m_importProperties->begin(), m_importProperties->end() );
657
658 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
659 props["page_width"] = std::to_string( GetPageSizeIU().x );
660 props["page_height"] = std::to_string( GetPageSizeIU().y );
661
662 pi->SetQueryUserCallback(
663 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
664 {
665 KIDIALOG dlg( nullptr, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
666
667 if( !aAction.IsEmpty() )
668 dlg.SetOKLabel( aAction );
669
670 dlg.DoNotShowCheckbox( aMessage, 0 );
671
672 return dlg.ShowModal() == wxID_OK;
673 } );
674
675#if USE_INSTRUMENTATION
676 // measure the time to load a BOARD.
677 int64_t startTime = GetRunningMicroSecs();
678#endif
679 // Use loadReporter for import issues - they will be shown in the status bar
680 // warning icon instead of a modal dialog
681 if( config()->m_System.show_import_issues )
682 pi->SetReporter( &loadReporter );
683 else
684 pi->SetReporter( &NULL_REPORTER::GetInstance() );
685
686 pi->SetProgressReporter( &progressReporter );
687 loadedBoard = pi->LoadBoard( fullFileName, nullptr, &props, &Prj() );
688
689#if USE_INSTRUMENTATION
690 int64_t stopTime = GetRunningMicroSecs();
691 printf( "PCB_IO::Load(): %u usecs\n", stopTime - startTime );
692#endif
693 }
694 catch( const FUTURE_FORMAT_ERROR& ffe )
695 {
696 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
697 progressReporter.Hide();
698 DisplayErrorMessage( this, msg, ffe.Problem() );
699
700 failedLoad = true;
701 }
702 catch( const IO_ERROR& ioe )
703 {
704 if( ioe.Problem() != wxT( "CANCEL" ) )
705 {
706 msg.Printf( _( "Error loading PCB '%s'." ), fullFileName );
707 progressReporter.Hide();
708 DisplayErrorMessage( this, msg, ioe.What() );
709 }
710
711 failedLoad = true;
712 }
713 catch( const std::bad_alloc& )
714 {
715 msg.Printf( _( "Memory exhausted loading PCB '%s'" ), fullFileName );
716 progressReporter.Hide();
717 DisplayErrorMessage( this, msg, wxEmptyString );
718
719 failedLoad = true;
720 }
721
722 if( failedLoad || !loadedBoard )
723 {
724 // We didn't create a new blank board above, so do that now
725 Clear_Pcb( false );
726
727 // Show any messages collected before the failure
728 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
729 statusBar->SetLoadWarningMessages( loadReporter.GetMessages() );
730
731 return false;
732 }
733
734 // This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
735 // cause any issues on macOS and Windows. If it does, it will have to be conditionally
736 // compiled.
737 Raise();
738
739 // Skip (possibly expensive) connectivity build here; we build it below after load
740 progressReporter.AddPhases( 1 );
741 progressReporter.AdvancePhase( _( "Finalizing board" ) );
742 progressReporter.KeepRefreshing();
743
744 PROF_TIMER postLoadTimer;
745 SetBoard( loadedBoard, false, &progressReporter );
746 wxLogTrace( traceAllegroPerf, wxT( "Post-load SetBoard: %.3f ms" ),
747 postLoadTimer.msecs( true ) );
748
749 if( loadedBoard->m_LegacyDesignSettingsLoaded )
750 {
751 Prj().SetReadOnly( false );
752
753 // Before we had a copper edge clearance setting, the edge line widths could be used
754 // as a kludge to control them. So if there's no setting then infer it from the
755 // edge widths.
756 if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
757 {
758 // Do not show the inferred edge clearance warning dialog when loading third
759 // party boards. For some reason the dialog completely hangs all of KiCad and
760 // the imported board cannot be saved.
761 int edgeClearance = inferLegacyEdgeClearance( loadedBoard, !converted );
762 loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance;
763 }
764
765 // On save; design settings will be removed from the board
766 loadedBoard->SetModified();
767 }
768
769 // Move legacy view settings to local project settings
770 if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
771 {
773 loadedBoard->SetModified();
774 }
775
777 {
779 loadedBoard->SetModified();
780 }
781
782 if( !loadedBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
783 {
784 m_infoBar->RemoveAllButtons();
785 m_infoBar->AddCloseButton();
786 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
787 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
788 }
789
790 // we should not ask PCB_IOs to do these items:
791 loadedBoard->BuildListOfNets();
792 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildListOfNets: %.3f ms" ),
793 postLoadTimer.msecs( true ) );
794
795 progressReporter.KeepRefreshing();
796
797 m_toolManager->RunAction( PCB_ACTIONS::repairBoard, true);
798 wxLogTrace( traceAllegroPerf, wxT( "Post-load repairBoard: %.3f ms" ),
799 postLoadTimer.msecs( true ) );
800
801 progressReporter.KeepRefreshing();
802
804 wxLogTrace( traceAllegroPerf, wxT( "Post-load rehatchShapes: %.3f ms" ),
805 postLoadTimer.msecs( true ) );
806
807 progressReporter.KeepRefreshing();
808
809 if( loadedBoard->IsModified() )
810 OnModify();
811 else
812 GetScreen()->SetContentModified( false );
813
814 if( ( pluginType == PCB_IO_MGR::LEGACY )
815 || ( pluginType == PCB_IO_MGR::KICAD_SEXP
817 && loadedBoard->GetGenerator().Lower() != wxT( "gerbview" ) ) )
818 {
819 m_infoBar->RemoveAllButtons();
820 m_infoBar->AddCloseButton();
821 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
822 "It will be converted to the new format when saved." ),
823 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
824 }
825
826 // TODO(JE) library tables -- I think this functionality should be deleted
827#if 0
828
829 // Import footprints into a project-specific library
830 //==================================================
831 // TODO: This should be refactored out of here into somewhere specific to the Project Import
832 // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
833 if( aCtl & KICTL_IMPORT_LIB )
834 {
835 wxFileName loadedBoardFn( fullFileName );
836 wxString libNickName = loadedBoardFn.GetName();
837
838 // Extract a footprint library from the design and add it to the fp-lib-table
839 // The footprints are saved in a new .pretty library.
840 // If this library already exists, all previous footprints will be deleted
841 std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
842 wxString newLibPath = CreateNewProjectLibrary( _( "New Footprint Library" ),
843 libNickName );
844
845 // Only create the new library if CreateNewLibrary succeeded (note that this fails if
846 // the library already exists and the user aborts after seeing the warning message
847 // which prompts the user to continue with overwrite or abort)
848 if( newLibPath.Length() > 0 )
849 {
851
852 for( FOOTPRINT* footprint : loadedFootprints )
853 {
854 try
855 {
856 if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
857 {
858 footprint->SetReference( "REF**" );
859 piSexpr->FootprintSave( newLibPath, footprint );
860 delete footprint;
861 }
862 }
863 catch( const IO_ERROR& ioe )
864 {
865 wxLogError( _( "Error saving footprint %s to project specific library." )
866 + wxS( "\n%s" ),
867 footprint->GetFPID().GetUniStringLibItemName(),
868 ioe.What() );
869 }
870 }
871
872 FP_LIB_TABLE* prjlibtable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
873 const wxString& project_env = PROJECT_VAR_NAME;
874 wxString rel_path, env_path;
875
876 wxASSERT_MSG( wxGetEnv( project_env, &env_path ),
877 wxT( "There is no project variable?" ) );
878
879 wxString result( newLibPath );
880
881 if( result.Replace( env_path, wxT( "$(" ) + project_env + wxT( ")" ) ) )
882 rel_path = result;
883
884 FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
885 wxT( "KiCad" ), wxEmptyString );
886 prjlibtable->InsertRow( row );
887
888 wxString tblName = Prj().FootprintLibTblName();
889
890 try
891 {
892 PROJECT_PCB::PcbFootprintLibs( &Prj() )->Save( tblName );
893 }
894 catch( const IO_ERROR& ioe )
895 {
896 wxLogError( _( "Error saving project specific footprint library table." )
897 + wxS( "\n%s" ),
898 ioe.What() );
899 }
900
901 // Update footprint LIB_IDs to point to the just imported library
902 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
903 {
904 LIB_ID libId = footprint->GetFPID();
905
906 if( libId.GetLibItemName().empty() )
907 continue;
908
909 libId.SetLibNickname( libNickName );
910 footprint->SetFPID( libId );
911 }
912 }
913 }
914#endif
915 }
916
917 {
918 wxString fname;
919
920 if( !previousBoardFileName.IsEmpty() && ( aCtl & KICTL_NONKICAD_ONLY ) && !setProject )
921 {
922 fname = previousBoardFileName;
923 }
924 else
925 {
926 wxFileName fn;
927
928 fn.SetPath( Prj().GetProjectPath() );
929 fn.SetName( Prj().GetProjectName() );
931
932 fname = fn.GetFullPath();
933
934 fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
935 }
936
937 GetBoard()->SetFileName( fname );
938 }
939
940 // Lock the file newly opened:
941 m_file_checker.reset( lock.release() );
942
943 if( !converted )
944 UpdateFileHistory( GetBoard()->GetFileName() );
945
946 std::vector<ZONE*> toFill;
947
948 // Rebuild list of nets (full ratsnest rebuild)
949 PROF_TIMER connectivityTimer;
950 GetBoard()->BuildConnectivity( &progressReporter );
951 wxLogTrace( traceAllegroPerf, wxT( "Post-load BuildConnectivity: %.3f ms" ),
952 connectivityTimer.msecs( true ) );
953
954 // Load project settings after setting up board; some of them depend on the nets list
957 wxLogTrace( traceAllegroPerf, wxT( "Post-load LoadProjectSettings+DrawingSheet: %.3f ms" ),
958 connectivityTimer.msecs( true ) );
959
960 // Resolve DRC exclusions after project settings are loaded
961 ResolveDRCExclusions( true );
962
963 // Initialise caches used by component classes
965
966 // Initialise time domain tuning caches
968 wxLogTrace( traceAllegroPerf, wxT( "Post-load DRC+ComponentClass+Tuning caches: %.3f ms" ),
969 connectivityTimer.msecs( true ) );
970
971 // Syncs the UI (appearance panel, etc) with the loaded board and project
973 wxLogTrace( traceAllegroPerf, wxT( "Post-load OnBoardLoaded: %.3f ms" ),
974 connectivityTimer.msecs( true ) );
975 wxLogTrace( traceAllegroPerf, wxT( "=== Post-load pipeline total: %.3f ms ===" ),
976 connectivityTimer.msecs() );
977
978 // Refresh the 3D view, if any
979 EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
980
981 if( draw3DFrame )
982 draw3DFrame->NewDisplay();
983#if 0 && defined(DEBUG)
984 // Output the board object tree to stdout, but please run from command prompt:
985 GetBoard()->Show( 0, std::cout );
986#endif
987
988 // from EDA_APPL which was first loaded BOARD only:
989 {
990 /* For an obscure reason the focus is lost after loading a board file
991 * when starting up the process.
992 * (seems due to the recreation of the layer manager after loading the file)
993 * Give focus to main window and Drawpanel
994 * must be done for these 2 windows (for an obscure reason ...)
995 * Linux specific
996 * This is more a workaround than a fix.
997 */
998 SetFocus();
999 GetCanvas()->SetFocus();
1000 }
1001
1002 if( !setProject )
1003 {
1004 // If we didn't reload the project, we still need to call ProjectChanged() to ensure
1005 // frame-specific initialization happens (like registering the autosave saver).
1006 // When running under the project manager, KIWAY::ProjectChanged() was called before
1007 // this frame existed, so we need to call our own ProjectChanged() now.
1009 }
1010
1011 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1012 statusBar->SetLoadWarningMessages( loadReporter.GetMessages() );
1013
1014 return true;
1015}
1016
1017
1018bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
1019 bool aChangeProject )
1020{
1021 // please, keep it simple. prompting goes elsewhere.
1022 wxFileName pcbFileName = aFileName;
1023
1024 if( pcbFileName.GetExt() == FILEEXT::LegacyPcbFileExtension )
1025 pcbFileName.SetExt( FILEEXT::KiCadPcbFileExtension );
1026
1027 // Write through symlinks, don't replace them
1029
1030 if( !IsWritable( pcbFileName ) )
1031 {
1032 wxString msg = wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1033 pcbFileName.GetFullPath() );
1034
1035 DisplayError( this, msg );
1036 return false;
1037 }
1038
1039 // TODO: these will break if we ever go multi-board
1040 wxFileName projectFile( pcbFileName );
1041 wxFileName rulesFile( pcbFileName );
1042 wxString msg;
1043
1044 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1045 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1046
1047 if( projectFile.FileExists() )
1048 {
1050 }
1051 else if( aChangeProject )
1052 {
1053 Prj().SetReadOnly( false );
1054 GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
1055 }
1056
1057 wxFileName currentRules( GetDesignRulesPath() );
1058
1059 if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
1060 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1061
1062 if( !msg.IsEmpty() )
1063 {
1064 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1065 rulesFile.GetFullPath() ) );
1066 }
1067
1068 if( projectFile.FileExists() )
1069 {
1070 // Save various DRC parameters, such as violation severities (which may have been
1071 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1073
1076 }
1077
1078 wxString upperTxt;
1079 wxString lowerTxt;
1080
1081 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1082 // hidden or read-only. This can happen when files are synced via cloud services.
1083 if( pcbFileName.FileExists() )
1084 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1085
1086 try
1087 {
1089
1090 pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1091 }
1092 catch( const IO_ERROR& ioe )
1093 {
1094 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1095 pcbFileName.GetFullPath(),
1096 ioe.What() ) );
1097 return false;
1098 }
1099
1100 if( !Kiface().IsSingle() )
1101 {
1102 WX_STRING_REPORTER backupReporter;
1103
1104 if( !GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1105 {
1106 upperTxt = backupReporter.GetMessages();
1107 SetStatusText( upperTxt, 1 );
1108 }
1109 }
1110
1111 GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1112
1113 // Update the lock in case it was a Save As
1114 LockFile( pcbFileName.GetFullPath() );
1115
1116 // Put the saved file in File History if requested
1117 if( addToHistory )
1118 UpdateFileHistory( GetBoard()->GetFileName() );
1119
1120 lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1121
1122 SetStatusText( lowerTxt, 0 );
1123
1124 // Get rid of the old version conversion warning, or any other dismissable warning :)
1125 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1126 m_infoBar->Dismiss();
1127
1128 if( m_infoBar->IsShownOnScreen() && m_infoBar->HasCloseButton() )
1129 m_infoBar->Dismiss();
1130
1131 GetScreen()->SetContentModified( false );
1132 UpdateTitle();
1134
1135 // Capture entire project state for PCB save events.
1136 Kiway().LocalHistory().CommitFullProjectSnapshot( pcbFileName.GetPath(), wxS( "PCB Save" ) );
1137 Kiway().LocalHistory().TagSave( pcbFileName.GetPath(), wxS( "pcb" ) );
1138
1139 if( m_autoSaveTimer )
1140 m_autoSaveTimer->Stop();
1141
1142 m_autoSavePending = false;
1143 m_autoSaveRequired = false;
1144 return true;
1145}
1146
1147
1148bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
1149{
1150 wxFileName pcbFileName( aFileName );
1151
1152 if( !IsWritable( pcbFileName ) )
1153 {
1154 if( !aHeadless )
1155 {
1156 DisplayError( this, wxString::Format( _( "Insufficient permissions to write file '%s'." ),
1157 pcbFileName.GetFullPath() ) );
1158 }
1159 return false;
1160 }
1161
1162 // Save various DRC parameters, such as violation severities (which may have been
1163 // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1165
1167
1168 // On Windows, ensure the target file is writeable by clearing problematic attributes like
1169 // hidden or read-only. This can happen when files are synced via cloud services.
1170 if( pcbFileName.FileExists() )
1171 KIPLATFORM::IO::MakeWriteable( pcbFileName.GetFullPath() );
1172
1173 try
1174 {
1176
1177 wxASSERT( pcbFileName.IsAbsolute() );
1178
1179 pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
1180 }
1181 catch( const IO_ERROR& ioe )
1182 {
1183 if( !aHeadless )
1184 {
1185 DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1186 pcbFileName.GetFullPath(),
1187 ioe.What() ) );
1188 }
1189
1190 return false;
1191 }
1192
1193 wxFileName projectFile( pcbFileName );
1194 wxFileName rulesFile( pcbFileName );
1195 wxString msg;
1196
1197 projectFile.SetExt( FILEEXT::ProjectFileExtension );
1198 rulesFile.SetExt( FILEEXT::DesignRulesFileExtension );
1199
1200 if( aCreateProject && !projectFile.FileExists() )
1201 GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1202
1203 wxFileName currentRules( GetDesignRulesPath() );
1204
1205 if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1206 KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1207
1208 if( !msg.IsEmpty() && !aHeadless )
1209 {
1210 DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1211 rulesFile.GetFullPath() ) );
1212 }
1213
1214 return true;
1215}
1216
1217
1218bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
1219 const std::map<std::string, UTF8>* aProperties )
1220{
1221 NULLER raiiNuller( (void*&) m_importProperties );
1222
1223 m_importProperties = aProperties;
1224
1225 switch( (PCB_IO_MGR::PCB_FILE_T) aFileType )
1226 {
1228 case PCB_IO_MGR::EAGLE:
1232 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_NONKICAD_ONLY | KICTL_IMPORT_LIB );
1233
1238 case PCB_IO_MGR::PADS:
1239 return OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_NONKICAD_ONLY );
1240
1241 default:
1242 return false;
1243 }
1244}
1245
1246
1248{
1250
1251 dlg.ShowModal();
1252
1253 return 0;
1254}
1255
1256
1258{
1260
1261 if( dlg.ShowModal() != wxID_OK )
1262 return 0;
1263
1265
1267 job.m_filename = m_frame->GetBoard()->GetFileName();
1269
1270 job.m_precision = dlg.GetPrecision();
1273
1274 WX_PROGRESS_REPORTER progressReporter( m_frame, _( "Generate ODB++ Files" ), 3, PR_CAN_ABORT );
1275 WX_STRING_REPORTER reporter;
1276
1277 DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( job, m_frame->GetBoard(), m_frame, &progressReporter, &reporter );
1278
1279 if( reporter.HasMessage() )
1280 DisplayError( m_frame, reporter.GetMessages() );
1281
1282 return 0;
1283}
const char * name
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetContentModified(bool aModified=true)
Definition base_screen.h:59
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:436
GAL_SET m_LegacyVisibleItems
Definition board.h:433
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1402
void BuildListOfNets()
Definition board.h:959
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:191
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2681
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition board.h:432
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:201
const wxString & GetFileName() const
Definition board.h:359
int GetFileFormatVersionAtLoad() const
Definition board.h:456
const wxString & GetGenerator() const
Adds an item to the container.
Definition board.h:459
void ClearProject()
Definition board.cpp:239
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1083
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:2495
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1407
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:2711
bool m_LegacyCopperEdgeClearanceLoaded
Definition board.h:437
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
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.
WX_INFOBAR * m_infoBar
wxTimer * m_autoSaveTimer
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxString GetMruPath() const
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
virtual void ClearFileHistory()
Remove all files from the file history.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
void SetMruPath(const wxString &aPath)
WX_INFOBAR * GetInfoBar()
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:110
bool IsModified() const
Definition eda_item.h:124
bool GetCreateNewProject() const
Gets the selected state of the copy subsheets option.
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:157
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.
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:407
Plugin class for import plugins that support remappable layers.
void SynchronizeTuningProfileProperties() const
Ensure time domain properties provider is synced with board / project settings if required.
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 TagSave(const wxString &aProjectPath, const wxString &aFileType)
Tag a manual save in the local history repository.
bool Init(const wxString &aProjectPath)
Initialize the local history repository for the given project path.
bool CommitFullProjectSnapshot(const wxString &aProjectPath, const wxString &aTitle)
Commit a snapshot of the entire project directory (excluding the .history directory and ignored trans...
Definition raii.h:38
static REPORTER & GetInstance()
Definition reporter.cpp:97
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:137
static TOOL_ACTION repairBoard
static TOOL_ACTION rehatchShapes
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.
void OnClearFileHistory(wxCommandEvent &aEvent)
bool SaveBoard(bool aSaveAs=false, bool aSaveCopy=false)
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
void ProjectChanged() override
Notification event that the project has changed.
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:97
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
@ GEDA_PCB
Geda PCB file formats.
Definition pcb_io_mgr.h:69
@ ALTIUM_DESIGNER
Definition pcb_io_mgr.h:63
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition pcb_io_mgr.h:59
@ ALTIUM_CIRCUIT_MAKER
Definition pcb_io_mgr.h:61
@ ALTIUM_CIRCUIT_STUDIO
Definition pcb_io_mgr.h:62
@ CADSTAR_PCB_ARCHIVE
Definition pcb_io_mgr.h:64
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
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
A small class to help profiling.
Definition profile.h:49
double msecs(bool aSinceLast=false)
Definition profile.h:149
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
void AddPhases(int aNumPhases) override
bool KeepRefreshing(bool aWait=false) override
Update the UI dialog.
Plugin class for import plugins that support choosing a project.
LSET m_VisibleLayers
Board settings.
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
virtual void SetReadOnly(bool aReadOnly=true)
Definition project.h:163
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:171
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:209
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition project.cpp:207
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition project.cpp:195
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.
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
bool empty() const
Definition utf8.h:109
static void ResolvePossibleSymlinks(wxFileName &aFilename)
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
A wrapper for reporting to a wxString object.
Definition reporter.h:191
const wxString & GetMessages() const
Definition reporter.cpp:78
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:629
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:259
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:230
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:131
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
#define _(s)
Declaration of the eda_3d_viewer class.
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition gestfich.cpp:293
#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 DesignRulesFileExtension
static const std::string KiCadPcbFileExtension
static wxString PcbFileWildcard()
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:642
#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:72
bool MakeWriteable(const wxString &aFilePath)
Ensures that a file has write permissions.
Definition unix/io.cpp:75
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:435
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
static const wxChar *const traceAllegroPerf
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition project.h:41
#define NAMELESS_PROJECT
default name for nameless projects
Definition project.h:44
KIWAY Kiway(KFCTL_STANDALONE)
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
std::string path
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