KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kicad_manager_control.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) 2019 CERN
5 * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22#include <executable_names.h>
23#include <pgm_base.h>
24#include <policy_keys.h>
25#include <kiway.h>
26#include <kicad_manager_frame.h>
27#include <kiplatform/policy.h>
28#include <confirm.h>
29#include <eda_tools.h>
34#include <tool/selection.h>
35#include <tool/tool_event.h>
39#include <gestfich.h>
40#include <paths.h>
41#include <wx/checkbox.h>
42#include <wx/dir.h>
43#include <wx/filedlg.h>
44#include "dialog_pcm.h"
45#include <macros.h>
46#include <sch_io_mgr.h>
47#include <io_mgr.h>
48#include <import_proj.h>
49
51
53 TOOL_INTERACTIVE( "kicad.Control" ),
54 m_frame( nullptr )
55{
56}
57
58
60{
61 m_frame = getEditFrame<KICAD_MANAGER_FRAME>();
62}
63
64
66{
67 wxString default_dir = m_frame->GetMruPath();
68 wxFileDialog dlg( m_frame, _( "Create New Project" ), default_dir, wxEmptyString,
69 ProjectFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
70
71 // Add a "Create a new directory" checkbox
72 FILEDLG_NEW_PROJECT newProjectHook;
73 dlg.SetCustomizeHook( newProjectHook );
74
75 if( dlg.ShowModal() == wxID_CANCEL )
76 return -1;
77
78 wxFileName pro( dlg.GetPath() );
79
80 // wxFileName automatically extracts an extension. But if it isn't
81 // a .pro extension, we should keep it as part of the filename
82 if( !pro.GetExt().IsEmpty() && pro.GetExt().ToStdString() != ProjectFileExtension )
83 pro.SetName( pro.GetName() + wxT( "." ) + pro.GetExt() );
84
85 pro.SetExt( ProjectFileExtension ); // enforce extension
86
87 if( !pro.IsAbsolute() )
88 pro.MakeAbsolute();
89
90 // Append a new directory with the same name of the project file.
91 bool createNewDir = false;
92
93 createNewDir = newProjectHook.GetCreateNewDir();
94
95 if( createNewDir )
96 pro.AppendDir( pro.GetName() );
97
98 // Check if the project directory is empty if it already exists.
99 wxDir directory( pro.GetPath() );
100
101 if( !pro.DirExists() )
102 {
103 if( !pro.Mkdir() )
104 {
105 wxString msg;
106 msg.Printf( _( "Folder '%s' could not be created.\n\n"
107 "Make sure you have write permissions and try again." ),
108 pro.GetPath() );
110 return -1;
111 }
112 }
113 else if( directory.HasFiles() )
114 {
115 wxString msg = _( "The selected folder is not empty. It is recommended that you "
116 "create projects in their own empty folder.\n\n"
117 "Do you want to continue?" );
118
119 if( !IsOK( m_frame, msg ) )
120 return -1;
121 }
122
124 m_frame->LoadProject( pro );
125
126 return 0;
127}
128
129
131{
133
134 wxFileName templatePath;
135
136 // KiCad system template path.
137 ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD7_TEMPLATE_DIR" );
138
139 if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
140 {
141 templatePath.AssignDir( it->second.GetValue() );
142 ps->AddTemplatesPage( _( "System Templates" ), templatePath );
143 }
144
145 // User template path.
146 it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" );
147
148 if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
149 {
150 templatePath.AssignDir( it->second.GetValue() );
151 ps->AddTemplatesPage( _( "User Templates" ), templatePath );
152 }
153
154 // Show the project template selector dialog
155 if( ps->ShowModal() != wxID_OK )
156 return -1;
157
158 if( !ps->GetSelectedTemplate() )
159 {
160 wxMessageBox( _( "No project template was selected. Cannot generate new project." ),
161 _( "Error" ), wxOK | wxICON_ERROR, m_frame );
162
163 return -1;
164 }
165
166 // Get project destination folder and project file name.
167 wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
168 wxString title = _( "New Project Folder" );
169 wxFileDialog dlg( m_frame, title, default_dir, wxEmptyString, ProjectFileWildcard(),
170 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
171
172 // Add a "Create a new directory" checkbox
173 FILEDLG_NEW_PROJECT newProjectHook;
174 dlg.SetCustomizeHook( newProjectHook );
175
176 if( dlg.ShowModal() == wxID_CANCEL )
177 return -1;
178
179 wxFileName fn( dlg.GetPath() );
180
181 // wxFileName automatically extracts an extension. But if it isn't a .kicad_pro extension,
182 // we should keep it as part of the filename
183 if( !fn.GetExt().IsEmpty() && fn.GetExt().ToStdString() != ProjectFileExtension )
184 fn.SetName( fn.GetName() + wxT( "." ) + fn.GetExt() );
185
186 fn.SetExt( ProjectFileExtension );
187
188 if( !fn.IsAbsolute() )
189 fn.MakeAbsolute();
190
191 bool createNewDir = false;
192 createNewDir = newProjectHook.GetCreateNewDir();
193
194 // Append a new directory with the same name of the project file.
195 if( createNewDir )
196 fn.AppendDir( fn.GetName() );
197
198 // Check if the project directory is empty if it already exists.
199
200 if( !fn.DirExists() )
201 {
202 if( !fn.Mkdir() )
203 {
204 wxString msg;
205 msg.Printf( _( "Folder '%s' could not be created.\n\n"
206 "Make sure you have write permissions and try again." ),
207 fn.GetPath() );
209 return -1;
210 }
211 }
212
213 if( !fn.IsDirWritable() )
214 {
215 wxString msg;
216
217 msg.Printf( _( "Insufficient permissions to write to folder '%s'." ), fn.GetPath() );
218 wxMessageDialog msgDlg( m_frame, msg, _( "Error" ), wxICON_ERROR | wxOK | wxCENTER );
219 msgDlg.ShowModal();
220 return -1;
221 }
222
223 // Make sure we are not overwriting anything in the destination folder.
224 std::vector< wxFileName > destFiles;
225
226 if( ps->GetSelectedTemplate()->GetDestinationFiles( fn, destFiles ) )
227 {
228 std::vector<wxFileName> overwrittenFiles;
229
230 for( const wxFileName& file : destFiles )
231 {
232 if( file.FileExists() )
233 overwrittenFiles.push_back( file );
234 }
235
236 if( !overwrittenFiles.empty() )
237 {
238 wxString extendedMsg = _( "Overwriting files:" ) + "\n";
239
240 for( const wxFileName& file : overwrittenFiles )
241 extendedMsg += "\n" + file.GetFullName();
242
243 KIDIALOG msgDlg( m_frame,
244 _( "Similar files already exist in the destination folder." ),
245 _( "Confirmation" ),
246 wxOK | wxCANCEL | wxICON_WARNING );
247 msgDlg.SetExtendedMessage( extendedMsg );
248 msgDlg.SetOKLabel( _( "Overwrite" ) );
249 msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
250
251 if( msgDlg.ShowModal() == wxID_CANCEL )
252 return -1;
253 }
254 }
255
256 wxString errorMsg;
257
258 // The selected template widget contains the template we're attempting to use to
259 // create a project
260 if( !ps->GetSelectedTemplate()->CreateProject( fn, &errorMsg ) )
261 {
262 wxMessageDialog createDlg( m_frame,
263 _( "A problem occurred creating new project from template." ),
264 _( "Error" ),
265 wxOK | wxICON_ERROR );
266
267 if( !errorMsg.empty() )
268 createDlg.SetExtendedMessage( errorMsg );
269
270 createDlg.ShowModal();
271 return -1;
272 }
273
274 m_frame->CreateNewProject( fn.GetFullPath() );
275 m_frame->LoadProject( fn );
276 return 0;
277}
278
279
280int KICAD_MANAGER_CONTROL::openProject( const wxString& aDefaultDir )
281{
282 wxString wildcard = AllProjectFilesWildcard()
283 + "|" + ProjectFileWildcard()
285
286 wxFileDialog dlg( m_frame, _( "Open Existing Project" ), aDefaultDir, wxEmptyString, wildcard,
287 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
288
289 if( dlg.ShowModal() == wxID_CANCEL )
290 return -1;
291
292 wxFileName pro( dlg.GetPath() );
293
294 if( !pro.IsAbsolute() )
295 pro.MakeAbsolute();
296
297 if( !pro.FileExists() )
298 return -1;
299
300 m_frame->LoadProject( pro );
301
302 return 0;
303}
304
305
307{
309}
310
311
313{
314 return openProject( m_frame->GetMruPath() );
315}
316
317
319{
320 m_frame->CloseProject( true );
321 return 0;
322}
323
324
326{
327 if( aEvent.Parameter<wxString*>() )
328 m_frame->LoadProject( wxFileName( *aEvent.Parameter<wxString*>() ) );
329 return 0;
330}
331
333{
334 if( aEvent.Parameter<wxString*>() )
335 wxExecute( *aEvent.Parameter<wxString*>(), wxEXEC_ASYNC );
336 return 0;
337}
338
339class SAVE_AS_TRAVERSER : public wxDirTraverser
340{
341public:
343 const wxString& aSrcProjectDirPath,
344 const wxString& aSrcProjectName,
345 const wxString& aNewProjectDirPath,
346 const wxString& aNewProjectName ) :
347 m_frame( aFrame ),
348 m_projectDirPath( aSrcProjectDirPath ),
349 m_projectName( aSrcProjectName ),
350 m_newProjectDirPath( aNewProjectDirPath ),
351 m_newProjectName( aNewProjectName )
352 {
353 }
354
355 virtual wxDirTraverseResult OnFile( const wxString& aSrcFilePath ) override
356 {
357 // Recursion guard for a Save As to a location inside the source project.
358 if( aSrcFilePath.StartsWith( m_newProjectDirPath + wxFileName::GetPathSeparator() ) )
359 return wxDIR_CONTINUE;
360
361 wxFileName destFile( aSrcFilePath );
362 wxString ext = destFile.GetExt();
363 bool atRoot = destFile.GetPath() == m_projectDirPath;
364
366 || ext == ProjectFileExtension
368 {
369 wxString destPath = destFile.GetPath();
370
371 if( destPath.StartsWith( m_projectDirPath ) )
372 {
373 destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
374 destFile.SetPath( destPath );
375 }
376
377 if( destFile.GetName() == m_projectName )
378 {
379 destFile.SetName( m_newProjectName );
380
381 if( atRoot && ext != ProjectLocalSettingsFileExtension )
382 m_newProjectFile = destFile;
383 }
384
385 if( ext == LegacyProjectFileExtension )
386 {
387 // All paths in the settings file are relative so we can just do a straight copy
388 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
389 }
390 else if( ext == ProjectFileExtension )
391 {
392 PROJECT_FILE projectFile( aSrcFilePath );
393 projectFile.LoadFromFile();
394 projectFile.SaveAs( destFile.GetPath(), destFile.GetName() );
395 }
396 else if( ext == ProjectLocalSettingsFileExtension )
397 {
398 PROJECT_LOCAL_SETTINGS projectLocalSettings( nullptr, aSrcFilePath );
399 projectLocalSettings.LoadFromFile();
400 projectLocalSettings.SaveAs( destFile.GetPath(), destFile.GetName() );
401 }
402 }
403 else if( ext == KiCadSchematicFileExtension
411 || ext == NetlistFileExtension
412 || destFile.GetName() == "sym-lib-table" )
413 {
416 m_newProjectName, aSrcFilePath, m_errors );
417 }
418 else if( ext == KiCadPcbFileExtension
420 || ext == LegacyPcbFileExtension
424 || destFile.GetName() == "fp-lib-table" )
425 {
428 m_newProjectName, aSrcFilePath, m_errors );
429 }
430 else if( ext == DrawingSheetFileExtension )
431 {
434 m_newProjectName, aSrcFilePath, m_errors );
435 }
436 else if( ext == GerberJobFileExtension
437 || ext == DrillFileExtension
438 || IsGerberFileExtension(ext) )
439 {
442 m_newProjectName, aSrcFilePath, m_errors );
443 }
444 else if(destFile.GetName().StartsWith( LockFilePrefix ) && ext == LockFileExtension )
445 {
446 // Ignore lock files
447 }
448 else
449 {
450 // Everything we don't recognize just gets a straight copy.
451 wxString destPath = destFile.GetPathWithSep();
452 wxString destName = destFile.GetName();
453 wxUniChar pathSep = wxFileName::GetPathSeparator();
454
455 wxString srcProjectFootprintLib = pathSep + m_projectName + ".pretty" + pathSep;
456 wxString newProjectFootprintLib = pathSep + m_newProjectName + ".pretty" + pathSep;
457
458 if( destPath.StartsWith( m_projectDirPath ) )
459 destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
460
461 destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib, true );
462
463 if( destName == m_projectName && ext != wxT( "zip" ) /* don't rename archives */ )
464 destFile.SetName( m_newProjectName );
465
466 destFile.SetPath( destPath );
467
468 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
469 }
470
471 return wxDIR_CONTINUE;
472 }
473
474 virtual wxDirTraverseResult OnDir( const wxString& aSrcDirPath ) override
475 {
476 // Recursion guard for a Save As to a location inside the source project.
477 if( aSrcDirPath.StartsWith( m_newProjectDirPath ) )
478 return wxDIR_CONTINUE;
479
480 wxFileName destDir( aSrcDirPath );
481 wxString destDirPath = destDir.GetPathWithSep();
482 wxUniChar pathSep = wxFileName::GetPathSeparator();
483
484 if( destDirPath.StartsWith( m_projectDirPath + pathSep )
485 || destDirPath.StartsWith( m_projectDirPath + PROJECT_BACKUPS_DIR_SUFFIX ) )
486 {
487 destDirPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
488 destDir.SetPath( destDirPath );
489 }
490
491 if( destDir.GetName() == m_projectName )
492 {
493 if( destDir.GetExt() == "pretty" )
494 destDir.SetName( m_newProjectName );
495#if 0
496 // WAYNE STAMBAUGH TODO:
497 // If we end up with a symbol equivalent to ".pretty" we'll want to handle it here....
498 else if( destDir.GetExt() == "sym_lib_dir_extension" )
499 destDir.SetName( m_newProjectName );
500#endif
501 }
502
503 if( !wxMkdir( destDir.GetFullPath() ) )
504 {
505 wxString msg;
506
507 if( !m_errors.empty() )
508 m_errors += "\n";
509
510 msg.Printf( _( "Cannot copy folder '%s'." ), destDir.GetFullPath() );
511 m_errors += msg;
512 }
513
514 return wxDIR_CONTINUE;
515 }
516
517 wxString GetErrors() { return m_errors; }
518
519 wxFileName GetNewProjectFile() { return m_newProjectFile; }
520
521private:
523
528
530 wxString m_errors;
531};
532
533
535{
536 wxString msg;
537
538 wxFileName currentProjectFile( Prj().GetProjectFullName() );
539 wxString currentProjectDirPath = currentProjectFile.GetPath();
540 wxString currentProjectName = Prj().GetProjectName();
541
542 wxString default_dir = m_frame->GetMruPath();
543
544 Prj().GetProjectFile().SaveToFile( currentProjectDirPath );
545 Prj().GetLocalSettings().SaveToFile( currentProjectDirPath );
546
547 if( default_dir == currentProjectDirPath
548 || default_dir == currentProjectDirPath + wxFileName::GetPathSeparator() )
549 {
550 // Don't start within the current project
551 wxFileName default_dir_fn( default_dir );
552 default_dir_fn.RemoveLastDir();
553 default_dir = default_dir_fn.GetPath();
554 }
555
556 wxFileDialog dlg( m_frame, _( "Save Project To" ), default_dir, wxEmptyString, wxEmptyString,
557 wxFD_SAVE );
558
559 if( dlg.ShowModal() == wxID_CANCEL )
560 return -1;
561
562 wxFileName newProjectDir( dlg.GetPath(), wxEmptyString );
563
564 if( !newProjectDir.IsAbsolute() )
565 newProjectDir.MakeAbsolute();
566
567 if( wxDirExists( newProjectDir.GetFullPath() ) )
568 {
569 msg.Printf( _( "'%s' already exists." ), newProjectDir.GetFullPath() );
571 return -1;
572 }
573
574 if( !wxMkdir( newProjectDir.GetFullPath() ) )
575 {
576 msg.Printf( _( "Folder '%s' could not be created.\n\n"
577 "Please make sure you have write permissions and try again." ),
578 newProjectDir.GetPath() );
580 return -1;
581 }
582
583 if( !newProjectDir.IsDirWritable() )
584 {
585 msg.Printf( _( "Insufficient permissions to write to folder '%s'." ),
586 newProjectDir.GetFullPath() );
587 wxMessageDialog msgDlg( m_frame, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
588 msgDlg.ShowModal();
589 return -1;
590 }
591
592 const wxString& newProjectDirPath = newProjectDir.GetFullPath();
593 const wxString& newProjectName = newProjectDir.GetDirs().Last();
594 wxDir currentProjectDir( currentProjectDirPath );
595
596 SAVE_AS_TRAVERSER traverser( m_frame, currentProjectDirPath, currentProjectName,
597 newProjectDirPath, newProjectName );
598
599 currentProjectDir.Traverse( traverser );
600
601 if( !traverser.GetErrors().empty() )
602 DisplayErrorMessage( m_frame, traverser.GetErrors() );
603
604 if( !traverser.GetNewProjectFile().FileExists() )
606
607 m_frame->LoadProject( traverser.GetNewProjectFile() );
608
609 return 0;
610}
611
612
614{
616 return 0;
617}
618
619
621{
622 ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
623 CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
624 SELECTION dummySel;
625
626 if( conditionalMenu )
627 conditionalMenu->Evaluate( dummySel );
628
629 if( actionMenu )
630 actionMenu->UpdateAll();
631
632 return 0;
633}
634
635
637{
638 FRAME_T playerType = aEvent.Parameter<FRAME_T>();
639 KIWAY_PLAYER* player;
640
641 if( playerType == FRAME_SCH && !m_frame->IsProjectActive() )
642 {
643 DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a schematic." ),
644 wxEmptyString );
645 return -1;
646 }
647 else if( playerType == FRAME_PCB_EDITOR && !m_frame->IsProjectActive() )
648 {
649 DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a pcb." ),
650 wxEmptyString );
651 return -1;
652 }
653
654 // Prevent multiple KIWAY_PLAYER loading at one time
655 if( !m_loading.try_lock() )
656 return -1;
657
658 const std::lock_guard<std::mutex> lock( m_loading, std::adopt_lock );
659
660 try
661 {
662 player = m_frame->Kiway().Player( playerType, true );
663 }
664 catch( const IO_ERROR& err )
665 {
666 wxLogError( _( "Application failed to load:\n" ) + err.What() );
667 return -1;
668 }
669
670 if ( !player )
671 {
672 wxLogError( _( "Application cannot start." ) );
673 return -1;
674 }
675
676 if( !player->IsVisible() ) // A hidden frame might not have the document loaded.
677 {
678 wxString filepath;
679
680 if( playerType == FRAME_SCH )
681 {
682 wxFileName kicad_schematic( m_frame->SchFileName() );
683 wxFileName legacy_schematic( m_frame->SchLegacyFileName() );
684
685 if( !legacy_schematic.FileExists() || kicad_schematic.FileExists() )
686 filepath = kicad_schematic.GetFullPath();
687 else
688 filepath = legacy_schematic.GetFullPath();
689 }
690 else if( playerType == FRAME_PCB_EDITOR )
691 {
692 wxFileName kicad_board( m_frame->PcbFileName() );
693 wxFileName legacy_board( m_frame->PcbLegacyFileName() );
694
695 if( !legacy_board.FileExists() || kicad_board.FileExists() )
696 filepath = kicad_board.GetFullPath();
697 else
698 filepath = legacy_board.GetFullPath();
699 }
700
701 if( !filepath.IsEmpty() )
702 {
703 std::vector<wxString> file_list{ filepath };
704
705 if( !player->OpenProjectFiles( file_list ) )
706 {
707 player->Destroy();
708 return -1;
709 }
710 }
711
712 wxBusyCursor busy;
713 player->Show( true );
714 }
715
716 // Needed on Windows, other platforms do not use it, but it creates no issue
717 if( player->IsIconized() )
718 player->Iconize( false );
719
720 player->Raise();
721
722 // Raising the window does not set the focus on Linux. This should work on
723 // any platform.
724 if( wxWindow::FindFocus() != player )
725 player->SetFocus();
726
727 // Save window state to disk now. Don't wait around for a crash.
728 if( Pgm().GetCommonSettings()->m_Session.remember_open_files
729 && !player->GetCurrentFileName().IsEmpty() )
730 {
731 wxFileName rfn( player->GetCurrentFileName() );
732 rfn.MakeRelativeTo( Prj().GetProjectPath() );
733
734 WINDOW_SETTINGS windowSettings;
735 player->SaveWindowSettings( &windowSettings );
736
737 Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &windowSettings, true );
738 Prj().GetLocalSettings().SaveToFile( Prj().GetProjectPath() );
739 }
740
741 return 0;
742}
743
744
745class TERMINATE_HANDLER : public wxProcess
746{
747public:
748 TERMINATE_HANDLER( const wxString& appName )
749 { }
750
751 void OnTerminate( int pid, int status ) override
752 {
753 delete this;
754 }
755};
756
757
759{
760 wxString execFile;
761 wxString param;
762
764 execFile = GERBVIEW_EXE;
766 execFile = BITMAPCONVERTER_EXE;
768 execFile = PCB_CALCULATOR_EXE;
770 execFile = PL_EDITOR_EXE;
772 execFile = Pgm().GetTextEditor();
774 execFile = EESCHEMA_EXE;
776 execFile = PCBNEW_EXE;
777 else
778 wxFAIL_MSG( "Execute(): unexpected request" );
779
780 if( execFile.IsEmpty() )
781 return 0;
782
783 if( aEvent.Parameter<wxString*>() )
784 param = *aEvent.Parameter<wxString*>();
786 param = m_frame->Prj().GetProjectPath();
787
788 TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( execFile );
789
790 long pid = ExecuteFile( execFile, param, callback );
791
792 if( pid > 0 )
793 {
794#ifdef __WXMAC__
795 // This non-parameterized use of wxExecute is fine because execFile is not derived
796 // from user input.
797 wxExecute( "osascript -e 'activate application \"" + execFile + "\"'" );
798#endif
799 }
800 else
801 {
802 delete callback;
803 }
804
805 return 0;
806}
807
808
810{
813 {
814 // policy disables the plugin manager
815 return 0;
816 }
817
818 // For some reason, after a click or a double click the bitmap button calling
819 // PCM keeps the focus althougt the focus was not set to this button.
820 // This hack force removing the focus from this button
821 m_frame->SetFocus();
822 wxSafeYield();
823
824 if( !m_frame->GetPcm() )
826
827 DIALOG_PCM pcm( m_frame, m_frame->GetPcm() );
828 pcm.ShowModal();
829
830 const std::unordered_set<PCM_PACKAGE_TYPE>& changed = pcm.GetChangedPackageTypes();
831
832 if( changed.count( PCM_PACKAGE_TYPE::PT_PLUGIN ) )
833 {
834 std::string payload = "";
836 }
837
838 KICAD_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<KICAD_SETTINGS>();
839
840 if( changed.count( PCM_PACKAGE_TYPE::PT_LIBRARY )
841 && ( settings->m_PcmLibAutoAdd || settings->m_PcmLibAutoRemove ) )
842 {
843 // Reset project tables
845 Prj().SetElem( PROJECT::ELEM_FPTBL, nullptr );
846
847 KIWAY& kiway = m_frame->Kiway();
848
849 // Reset state containing global lib tables
850 if( KIFACE* kiface = kiway.KiFACE( KIWAY::FACE_SCH, false ) )
851 kiface->Reset();
852
853 if( KIFACE* kiface = kiway.KiFACE( KIWAY::FACE_PCB, false ) )
854 kiface->Reset();
855
856 // Reload lib tables
857 std::string payload = "";
858
861 kiway.ExpressMail( FRAME_CVPCB, MAIL_RELOAD_LIB, payload );
864 }
865
866 if( changed.count( PCM_PACKAGE_TYPE::PT_COLORTHEME ) )
867 Pgm().GetSettingsManager().ReloadColorSettings();
868
869 return 0;
870}
871
872
874{
883
886
896
899
901}
static TOOL_ACTION zoomRedraw
Definition: actions.h:94
static TOOL_ACTION saveAs
Definition: actions.h:52
static TOOL_ACTION updateMenu
Definition: actions.h:180
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:49
void UpdateAll()
Run update handlers for the menu and its submenus.
Implementing pcm main dialog.
Definition: dialog_pcm.h:36
const std::unordered_set< PCM_PACKAGE_TYPE > & GetChangedPackageTypes() const
Definition: dialog_pcm.h:77
void AddTemplatesPage(const wxString &aTitle, wxFileName &aPath)
Add a new page with aTitle, populated with templates from aPath.
PROJECT_TEMPLATE * GetSelectedTemplate()
wxString GetMruPath() const
bool GetCreateNewDir() const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual bool LoadFromFile(const wxString &aDirectory="")
Loads the backing file from disk and then calls Load()
static TOOL_ACTION viewDroppedGerbers
static TOOL_ACTION openDemoProject
static TOOL_ACTION editPCB
static TOOL_ACTION loadProject
static TOOL_ACTION editOtherPCB
static TOOL_ACTION newProject
static TOOL_ACTION editOtherSch
static TOOL_ACTION editSchematic
static TOOL_ACTION openTextEditor
static TOOL_ACTION openProject
static TOOL_ACTION closeProject
static TOOL_ACTION convertImage
static TOOL_ACTION editDrawingSheet
static TOOL_ACTION editFootprints
static TOOL_ACTION showPluginManager
static TOOL_ACTION showCalculator
static TOOL_ACTION viewGerbers
static TOOL_ACTION newFromTemplate
static TOOL_ACTION editSymbols
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int OpenProject(const TOOL_EVENT &aEvent)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int OpenDemoProject(const TOOL_EVENT &aEvent)
int CloseProject(const TOOL_EVENT &aEvent)
int SaveProjectAs(const TOOL_EVENT &aEvent)
int NewProject(const TOOL_EVENT &aEvent)
int ViewDroppedViewers(const TOOL_EVENT &aEvent)
Imports a non kicad project from a sch/pcb dropped file.
int NewFromTemplate(const TOOL_EVENT &aEvent)
int ShowPluginManager(const TOOL_EVENT &aEvent)
Set up handlers for various events.
int UpdateMenu(const TOOL_EVENT &aEvent)
int LoadProject(const TOOL_EVENT &aEvent)
KICAD_MANAGER_FRAME * m_frame
< Pointer to the currently used edit/draw frame.
int ShowPlayer(const TOOL_EVENT &aEvent)
int Refresh(const TOOL_EVENT &aEvent)
int openProject(const wxString &aDefaultDir)
int Execute(const TOOL_EVENT &aEvent)
The main KiCad project manager frame.
void CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
const wxString SchLegacyFileName()
const wxString SchFileName()
void LoadProject(const wxFileName &aProjectFileName)
std::shared_ptr< PLUGIN_CONTENT_MANAGER > GetPcm()
const wxString PcbLegacyFileName()
bool CloseProject(bool aSave)
Closes the project, and saves it if aSave is true;.
const wxString PcbFileName()
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:47
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:56
int ShowModal() override
Definition: confirm.cpp:100
virtual void Reset() override
Reloads global state.
Definition: kiface_base.h:55
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:66
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:432
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
@ FACE_SCH
eeschema DSO
Definition: kiway.h:286
@ FACE_PL_EDITOR
Definition: kiway.h:290
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:287
@ FACE_GERBVIEW
Definition: kiway.h:289
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:553
static wxString GetStockDemosPath()
Gets the stock (install) demos path.
Definition: paths.cpp:328
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:69
bool SaveAs(const wxString &aDirectory, const wxString &aFile)
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
The project local settings are things that are attached to a particular project, but also might be pa...
bool SaveAs(const wxString &aDirectory, const wxString &aFile)
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
void SaveFileState(const wxString &aFileName, const WINDOW_SETTINGS *aWindowCfg, bool aOpen)
size_t GetDestinationFiles(const wxFileName &aNewProjectPath, std::vector< wxFileName > &aDestFiles)
Fetch the list of destination files to be copied when the new project is created.
bool CreateProject(wxFileName &aNewProjectPath, wxString *aErrorMsg=nullptr)
Copies and renames all template files to create a new project.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:143
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:155
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:172
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:317
@ ELEM_SYMBOL_LIB_TABLE
Definition: project.h:228
@ ELEM_FPTBL
Definition: project.h:223
KICAD_MANAGER_FRAME * m_frame
virtual wxDirTraverseResult OnFile(const wxString &aSrcFilePath) override
SAVE_AS_TRAVERSER(KICAD_MANAGER_FRAME *aFrame, const wxString &aSrcProjectDirPath, const wxString &aSrcProjectName, const wxString &aNewProjectDirPath, const wxString &aNewProjectName)
virtual wxDirTraverseResult OnDir(const wxString &aSrcDirPath) override
void OnTerminate(int pid, int status) override
TERMINATE_HANDLER(const wxString &appName)
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:81
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:461
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:332
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:305
This file is part of the common library.
#define _(s)
Enums and utilities for different EDA tools.
KiCad executable names.
const wxString EESCHEMA_EXE
const wxString GERBVIEW_EXE
const wxString PL_EDITOR_EXE
const wxString BITMAPCONVERTER_EXE
const wxString PCBNEW_EXE
const wxString PCB_CALCULATOR_EXE
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:33
@ FRAME_PCB_EDITOR
Definition: frame_type.h:40
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ FRAME_FOOTPRINT_VIEWER
Definition: frame_type.h:43
@ FRAME_SCH_VIEWER
Definition: frame_type.h:36
@ FRAME_SCH
Definition: frame_type.h:34
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:41
@ FRAME_CVPCB
Definition: frame_type.h:48
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition: gestfich.cpp:276
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback)
Call the executable file aEditorName with the parameter aFileName.
Definition: gestfich.cpp:118
const std::string LegacyPcbFileExtension
const std::string BackupFileSuffix
const std::string KiCadSymbolLibFileExtension
const std::string LegacySchematicFileExtension
const std::string FootprintAssignmentFileExtension
const std::string GerberJobFileExtension
const std::string LegacySymbolDocumentFileExtension
const std::string DrillFileExtension
const std::string LockFilePrefix
const std::string KiCadFootprintFileExtension
const std::string LegacyProjectFileExtension
const std::string KiCadPcbFileExtension
bool IsGerberFileExtension(const wxString &ext)
const std::string LegacyFootprintLibPathExtension
const std::string ProjectLocalSettingsFileExtension
const std::string ProjectFileExtension
const std::string NetlistFileExtension
const std::string LockFileExtension
const std::string KiCadSchematicFileExtension
const std::string DrawingSheetFileExtension
const std::string SchematicSymbolFileExtension
const std::string LegacySymbolLibFileExtension
wxString AllProjectFilesWildcard()
wxString LegacyProjectFileWildcard()
wxString ProjectFileWildcard()
std::map< wxString, ENV_VAR_ITEM >::const_iterator ENV_VAR_MAP_CITER
PROJECT & Prj()
Definition: kicad.cpp:571
This file contains miscellaneous commonly used macros and functions.
@ MAIL_RELOAD_PLUGINS
Definition: mail_type.h:57
@ MAIL_RELOAD_LIB
Definition: mail_type.h:56
PBOOL GetPolicyBool(const wxString &aKey)
Definition: gtk/policy.cpp:26
see class PGM_BASE
#define POLICY_KEY_PCM
Definition: policy_keys.h:31
#define PROJECT_BACKUPS_DIR_SUFFIX
Project settings path will be <projectname> + this.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:151
virtual void SaveFileAs(const wxString &srcProjectBasePath, const wxString &srcProjectName, const wxString &newProjectBasePath, const wxString &newProjectName, const wxString &srcFilePath, wxString &aErrors)
Saving a file under a different name is delegated to the various KIFACEs because the project doesn't ...
Definition: kiway.h:216
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:74
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
Definition of file extensions used in Kicad.