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