KiCad PCB EDA Suite
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-2021 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 <kiway.h>
25 #include <kicad_manager_frame.h>
26 #include <confirm.h>
27 #include <tool/selection.h>
28 #include <tool/tool_event.h>
32 #include <gestfich.h>
33 #include <paths.h>
34 #include <wx/checkbox.h>
35 #include <wx/dir.h>
36 #include <wx/filedlg.h>
37 #ifdef PCM
38 #include "dialog_pcm.h"
39 #endif
40 
41 
43 class DIR_CHECKBOX : public wxPanel
44 {
45 public:
46  DIR_CHECKBOX( wxWindow* aParent )
47  : wxPanel( aParent )
48  {
49  m_cbCreateDir = new wxCheckBox( this, wxID_ANY,
50  _( "Create a new folder for the project" ) );
51  m_cbCreateDir->SetValue( true );
52 
53  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
54  sizer->Add( m_cbCreateDir, 0, wxALL, 8 );
55 
56  SetSizerAndFit( sizer );
57  }
58 
59  bool CreateNewDir() const
60  {
61  return m_cbCreateDir->GetValue();
62  }
63 
64  static wxWindow* Create( wxWindow* aParent )
65  {
66  return new DIR_CHECKBOX( aParent );
67  }
68 
69 protected:
70  wxCheckBox* m_cbCreateDir;
71 };
72 
73 
75  TOOL_INTERACTIVE( "kicad.Control" ),
76  m_frame( nullptr )
77 {
78 }
79 
80 
82 {
83  m_frame = getEditFrame<KICAD_MANAGER_FRAME>();
84 }
85 
86 
88 {
89  wxString default_dir = m_frame->GetMruPath();
90  wxFileDialog dlg( m_frame, _( "Create New Project" ), default_dir, wxEmptyString,
91  ProjectFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
92 
93  // Add a "Create a new directory" checkbox
94  dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
95 
96  if( dlg.ShowModal() == wxID_CANCEL )
97  return -1;
98 
99  wxFileName pro( dlg.GetPath() );
100 
101  // wxFileName automatically extracts an extension. But if it isn't
102  // a .pro extension, we should keep it as part of the filename
103  if( !pro.GetExt().IsEmpty() && pro.GetExt().ToStdString() != ProjectFileExtension )
104  pro.SetName( pro.GetName() + wxT( "." ) + pro.GetExt() );
105 
106  pro.SetExt( ProjectFileExtension ); // enforce extension
107 
108  if( !pro.IsAbsolute() )
109  pro.MakeAbsolute();
110 
111  // Append a new directory with the same name of the project file.
112  if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
113  pro.AppendDir( pro.GetName() );
114 
115  // Check if the project directory is empty if it already exists.
116  wxDir directory( pro.GetPath() );
117 
118  if( !pro.DirExists() )
119  {
120  if( !pro.Mkdir() )
121  {
122  wxString msg;
123  msg.Printf( _( "Folder '%s' could not be created.\n\n"
124  "Make sure you have write permissions and try again." ),
125  pro.GetPath() );
127  return -1;
128  }
129  }
130  else if( directory.HasFiles() )
131  {
132  wxString msg = _( "The selected folder is not empty. It is recommended that you "
133  "create projects in their own empty folder.\n\n"
134  "Do you want to continue?" );
135 
136  if( !IsOK( m_frame, msg ) )
137  return -1;
138  }
139 
140  m_frame->CreateNewProject( pro );
141  m_frame->LoadProject( pro );
142 
143  return 0;
144 }
145 
146 
148 {
150 
151  wxFileName templatePath;
152  wxString envStr;
153 
154  // KiCad system template path.
155  ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD6_TEMPLATE_DIR" );
156 
157  if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
158  {
159  templatePath.AssignDir( it->second.GetValue() );
160  ps->AddTemplatesPage( _( "System Templates" ), templatePath );
161  }
162 
163  // User template path.
164  it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" );
165 
166  if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
167  {
168  templatePath.AssignDir( it->second.GetValue() );
169  ps->AddTemplatesPage( _( "User Templates" ), templatePath );
170  }
171 
172  // Show the project template selector dialog
173  if( ps->ShowModal() != wxID_OK )
174  return -1;
175 
176  if( !ps->GetSelectedTemplate() )
177  {
178  wxMessageBox( _( "No project template was selected. Cannot generate new project." ),
179  _( "Error" ), wxOK | wxICON_ERROR, m_frame );
180 
181  return -1;
182  }
183 
184  // Get project destination folder and project file name.
185  wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
186  wxString title = _( "New Project Folder" );
187  wxFileDialog dlg( m_frame, title, default_dir, wxEmptyString, ProjectFileWildcard(),
188  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
189 
190  // Add a "Create a new directory" checkbox
191  dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
192 
193  if( dlg.ShowModal() == wxID_CANCEL )
194  return -1;
195 
196  wxFileName fn( dlg.GetPath() );
197 
198  // wxFileName automatically extracts an extension. But if it isn't a .kicad_pro extension,
199  // we should keep it as part of the filename
200  if( !fn.GetExt().IsEmpty() && fn.GetExt().ToStdString() != ProjectFileExtension )
201  fn.SetName( fn.GetName() + wxT( "." ) + fn.GetExt() );
202 
203  fn.SetExt( ProjectFileExtension );
204 
205  if( !fn.IsAbsolute() )
206  fn.MakeAbsolute();
207 
208  // Append a new directory with the same name of the project file.
209  if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
210  fn.AppendDir( fn.GetName() );
211 
212  // Check if the project directory is empty if it already exists.
213  wxDir directory( fn.GetPath() );
214 
215  if( !fn.DirExists() )
216  {
217  if( !fn.Mkdir() )
218  {
219  wxString msg;
220  msg.Printf( _( "Folder '%s' could not be created.\n\n"
221  "Make sure you have write permissions and try again." ),
222  fn.GetPath() );
224  return -1;
225  }
226  }
227 
228  if( !fn.IsDirWritable() )
229  {
230  wxString msg;
231 
232  msg.Printf( _( "Insufficient permissions to write to folder '%s'." ), fn.GetPath() );
233  wxMessageDialog msgDlg( m_frame, msg, _( "Error" ), wxICON_ERROR | wxOK | wxCENTER );
234  msgDlg.ShowModal();
235  return -1;
236  }
237 
238  // Make sure we are not overwriting anything in the destination folder.
239  std::vector< wxFileName > destFiles;
240 
241  if( ps->GetSelectedTemplate()->GetDestinationFiles( fn, destFiles ) )
242  {
243  std::vector< wxFileName > overwrittenFiles;
244 
245  for( const auto& file : destFiles )
246  {
247  if( file.FileExists() )
248  overwrittenFiles.push_back( file );
249  }
250 
251  if( !overwrittenFiles.empty() )
252  {
253  wxString extendedMsg = _( "Overwriting files:" ) + "\n";
254 
255  for( const auto& file : overwrittenFiles )
256  extendedMsg += "\n" + file.GetFullName();
257 
258  KIDIALOG msgDlg( m_frame, _( "Similar files already exist in the destination folder." ),
259  _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
260  msgDlg.SetExtendedMessage( extendedMsg );
261  msgDlg.SetOKLabel( _( "Overwrite" ) );
262  msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
263 
264  if( msgDlg.ShowModal() == wxID_CANCEL )
265  return -1;
266  }
267  }
268 
269  wxString errorMsg;
270 
271  // The selected template widget contains the template we're attempting to use to
272  // create a project
273  if( !ps->GetSelectedTemplate()->CreateProject( fn, &errorMsg ) )
274  {
275  wxMessageDialog createDlg( m_frame,
276  _( "A problem occurred creating new project from template." ),
277  _( "Error" ),
278  wxOK | wxICON_ERROR );
279 
280  if( !errorMsg.empty() )
281  createDlg.SetExtendedMessage( errorMsg );
282 
283  createDlg.ShowModal();
284  return -1;
285  }
286 
287  m_frame->CreateNewProject( fn.GetFullPath() );
288  m_frame->LoadProject( fn );
289  return 0;
290 }
291 
292 
293 int KICAD_MANAGER_CONTROL::openProject( const wxString& aDefaultDir )
294 {
295  wxString wildcard = AllProjectFilesWildcard() + "|" + ProjectFileWildcard() + "|"
297 
298  wxFileDialog dlg( m_frame, _( "Open Existing Project" ), aDefaultDir, wxEmptyString, wildcard,
299  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
300 
301  if( dlg.ShowModal() == wxID_CANCEL )
302  return -1;
303 
304  wxFileName pro( dlg.GetPath() );
305 
306  if( !pro.IsAbsolute() )
307  pro.MakeAbsolute();
308 
309  if( !pro.FileExists() )
310  return -1;
311 
312  m_frame->LoadProject( pro );
313 
314  return 0;
315 }
316 
317 
319 {
321 }
322 
323 
325 {
326  return openProject( m_frame->GetMruPath() );
327 }
328 
329 
331 {
332  m_frame->CloseProject( true );
333  return 0;
334 }
335 
336 
337 class SAVE_AS_TRAVERSER : public wxDirTraverser
338 {
339 public:
341  const wxString& aSrcProjectDirPath,
342  const wxString& aSrcProjectName,
343  const wxString& aNewProjectDirPath,
344  const wxString& aNewProjectName ) :
345  m_frame( aFrame ),
346  m_projectDirPath( aSrcProjectDirPath ),
347  m_projectName( aSrcProjectName ),
348  m_newProjectDirPath( aNewProjectDirPath ),
349  m_newProjectName( aNewProjectName )
350  {
351  }
352 
353  virtual wxDirTraverseResult OnFile( const wxString& aSrcFilePath ) override
354  {
355  // Recursion guard for a Save As to a location inside the source project.
356  if( aSrcFilePath.StartsWith( m_newProjectDirPath ) )
357  return wxDIR_CONTINUE;
358 
359  wxFileName destFile( aSrcFilePath );
360  wxString ext = destFile.GetExt();
361  bool atRoot = destFile.GetPath() == m_projectDirPath;
362 
363  if( ext == "pro" )
364  {
365  wxString destPath = destFile.GetPath();
366 
367  if( destPath.StartsWith( m_projectDirPath ) )
368  {
369  destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
370  destFile.SetPath( destPath );
371  }
372 
373  if( destFile.GetName() == m_projectName )
374  {
375  destFile.SetName( m_newProjectName );
376 
377  if( atRoot )
378  m_newProjectFile = destFile;
379  }
380 
381  // Currently all paths in the settings file are relative, so we can just do a
382  // straight copy
383  KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
384  }
385  else if( ext == KiCadSchematicFileExtension
393  || ext == NetlistFileExtension
394  || destFile.GetName() == "sym-lib-table" )
395  {
398  m_newProjectName, aSrcFilePath, m_errors );
399  }
400  else if( ext == KiCadPcbFileExtension
402  || ext == LegacyPcbFileExtension
406  || destFile.GetName() == "fp-lib-table" )
407  {
410  m_newProjectName, aSrcFilePath, m_errors );
411  }
412  else if( ext == DrawingSheetFileExtension )
413  {
414  KIFACE* pleditor = m_frame->Kiway().KiFACE( KIWAY::FACE_PL_EDITOR );
416  m_newProjectName, aSrcFilePath, m_errors );
417  }
418  else if( ext == GerberFileExtension
419  || ext == GerberJobFileExtension
420  || ext == DrillFileExtension
421  || IsProtelExtension( ext ) )
422  {
423  KIFACE* gerbview = m_frame->Kiway().KiFACE( KIWAY::FACE_GERBVIEW );
425  m_newProjectName, aSrcFilePath, m_errors );
426  }
427  else
428  {
429  // Everything we don't recognize just gets a straight copy.
430  wxString destPath = destFile.GetPathWithSep();
431  wxString destName = destFile.GetName();
432  wxUniChar pathSep = wxFileName::GetPathSeparator();
433 
434  wxString srcProjectFootprintLib = pathSep + m_projectName + ".pretty" + pathSep;
435  wxString newProjectFootprintLib = pathSep + m_newProjectName + ".pretty" + pathSep;
436 
437  if( destPath.StartsWith( m_projectDirPath ) )
438  {
439  destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
440  destFile.SetPath( destPath );
441  }
442 
443  if( destName == m_projectName )
444  destFile.SetName( m_newProjectName );
445 
446  destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib, true );
447  destFile.SetPath( destPath );
448 
449 
450  KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
451  }
452 
453  return wxDIR_CONTINUE;
454  }
455 
456  virtual wxDirTraverseResult OnDir( const wxString& aSrcDirPath ) override
457  {
458  // Recursion guard for a Save As to a location inside the source project.
459  if( aSrcDirPath.StartsWith( m_newProjectDirPath ) )
460  return wxDIR_CONTINUE;
461 
462  wxFileName destDir( aSrcDirPath );
463  wxString destDirPath = destDir.GetPathWithSep();
464  wxUniChar pathSep = wxFileName::GetPathSeparator();
465 
466  if( destDirPath.StartsWith( m_projectDirPath + pathSep ) )
467  {
468  destDirPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
469  destDir.SetPath( destDirPath );
470  }
471 
472  if( destDir.GetName() == m_projectName )
473  {
474  if( destDir.GetExt() == "pretty" )
475  destDir.SetName( m_newProjectName );
476 #if 0
477  // WAYNE STAMBAUGH TODO:
478  // If we end up with a symbol equivalent to ".pretty" we'll want to handle it here....
479  else if( destDir.GetExt() == "sym_lib_dir_extension" )
480  destDir.SetName( m_newProjectName );
481 #endif
482  }
483 
484  if( !wxMkdir( destDir.GetFullPath() ) )
485  {
486  wxString msg;
487 
488  if( !m_errors.empty() )
489  m_errors += "\n";
490 
491  msg.Printf( _( "Cannot copy folder '%s'." ), destDir.GetFullPath() );
492  m_errors += msg;
493  }
494 
495  return wxDIR_CONTINUE;
496  }
497 
498  wxString GetErrors() { return m_errors; }
499 
500  wxFileName GetNewProjectFile() { return m_newProjectFile; }
501 
502 private:
504 
506  wxString m_projectName;
509 
510  wxFileName m_newProjectFile;
511  wxString m_errors;
512 };
513 
514 
516 {
517  wxString msg;
518 
519  wxFileName currentProjectFile( Prj().GetProjectFullName() );
520  wxString currentProjectDirPath = currentProjectFile.GetPath();
521  wxString currentProjectName = Prj().GetProjectName();
522 
523  wxString default_dir = m_frame->GetMruPath();
524 
525  if( default_dir == currentProjectDirPath
526  || default_dir == currentProjectDirPath + wxFileName::GetPathSeparator() )
527  {
528  // Don't start within the current project
529  wxFileName default_dir_fn( default_dir );
530  default_dir_fn.RemoveLastDir();
531  default_dir = default_dir_fn.GetPath();
532  }
533 
534  wxFileDialog dlg( m_frame, _( "Save Project To" ), default_dir, wxEmptyString, wxEmptyString,
535  wxFD_SAVE );
536 
537  if( dlg.ShowModal() == wxID_CANCEL )
538  return -1;
539 
540  wxFileName newProjectDir( dlg.GetPath() );
541 
542  if( !newProjectDir.IsAbsolute() )
543  newProjectDir.MakeAbsolute();
544 
545  if( wxDirExists( newProjectDir.GetFullPath() ) )
546  {
547  msg.Printf( _( "'%s' already exists." ), newProjectDir.GetFullPath() );
549  return -1;
550  }
551 
552  if( !wxMkdir( newProjectDir.GetFullPath() ) )
553  {
554  msg.Printf( _( "Folder '%s' could not be created.\n\n"
555  "Please make sure you have write permissions and try again." ),
556  newProjectDir.GetPath() );
558  return -1;
559  }
560 
561  if( !newProjectDir.IsDirWritable() )
562  {
563  msg.Printf( _( "Insufficient permissions to write to folder '%s'." ),
564  newProjectDir.GetFullPath() );
565  wxMessageDialog msgDlg( m_frame, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
566  msgDlg.ShowModal();
567  return -1;
568  }
569 
570  const wxString& newProjectDirPath = newProjectDir.GetFullPath();
571  const wxString& newProjectName = newProjectDir.GetName();
572  wxDir currentProjectDir( currentProjectDirPath );
573 
574  SAVE_AS_TRAVERSER traverser( m_frame, currentProjectDirPath, currentProjectName,
575  newProjectDirPath, newProjectName );
576 
577  currentProjectDir.Traverse( traverser );
578 
579  if( !traverser.GetErrors().empty() )
580  DisplayErrorMessage( m_frame, traverser.GetErrors() );
581 
582  if( traverser.GetNewProjectFile().FileExists() )
583  {
585  m_frame->LoadProject( traverser.GetNewProjectFile() );
586  }
587 
588  return 0;
589 }
590 
591 
593 {
595  return 0;
596 }
597 
598 
600 {
601  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
602  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
603  SELECTION dummySel;
604 
605  if( conditionalMenu )
606  conditionalMenu->Evaluate( dummySel );
607 
608  if( actionMenu )
609  actionMenu->UpdateAll();
610 
611  return 0;
612 }
613 
614 
616 {
617  FRAME_T playerType = aEvent.Parameter<FRAME_T>();
618  KIWAY_PLAYER* player;
619 
620  if( playerType == FRAME_SCH && !m_frame->IsProjectActive() )
621  {
622  DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a schematic." ),
623  wxEmptyString );
624  return -1;
625  }
626  else if( playerType == FRAME_PCB_EDITOR && !m_frame->IsProjectActive() )
627  {
628  DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a pcb." ),
629  wxEmptyString );
630  return -1;
631  }
632 
633  // Prevent multiple KIWAY_PLAYER loading at one time
634  if( !m_loading.try_lock() )
635  return -1;
636 
637  const std::lock_guard<std::mutex> lock( m_loading, std::adopt_lock );
638 
639  try
640  {
641  player = m_frame->Kiway().Player( playerType, true );
642  }
643  catch( const IO_ERROR& err )
644  {
645  wxMessageBox( _( "Application failed to load:\n" ) + err.What(), _( "KiCad Error" ),
646  wxOK | wxICON_ERROR, m_frame );
647  return -1;
648  }
649 
650  if ( !player )
651  {
652  wxMessageBox( _( "Application failed to load." ), _( "KiCad Error" ),
653  wxOK | wxICON_ERROR, m_frame );
654  return -1;
655  }
656 
657  if( !player->IsVisible() ) // A hidden frame might not have the document loaded.
658  {
659  wxString filepath;
660 
661  if( playerType == FRAME_SCH )
662  {
663  wxFileName kicad_schematic( m_frame->SchFileName() );
664  wxFileName legacy_schematic( m_frame->SchLegacyFileName() );
665 
666  if( !legacy_schematic.FileExists() || kicad_schematic.FileExists() )
667  filepath = kicad_schematic.GetFullPath();
668  else
669  filepath = legacy_schematic.GetFullPath();
670  }
671  else if( playerType == FRAME_PCB_EDITOR )
672  {
673  wxFileName kicad_board( m_frame->PcbFileName() );
674  wxFileName legacy_board( m_frame->PcbLegacyFileName() );
675 
676  if( !legacy_board.FileExists() || kicad_board.FileExists() )
677  filepath = kicad_board.GetFullPath();
678  else
679  filepath = legacy_board.GetFullPath();
680  }
681 
682  if( !filepath.IsEmpty() )
683  {
684  if( !player->OpenProjectFiles( std::vector<wxString>( 1, filepath ) ) )
685  {
686  player->Destroy();
687  return -1;
688  }
689  }
690 
691  player->Show( true );
692  }
693 
694  // Needed on Windows, other platforms do not use it, but it creates no issue
695  if( player->IsIconized() )
696  player->Iconize( false );
697 
698  player->Raise();
699 
700  // Raising the window does not set the focus on Linux. This should work on
701  // any platform.
702  if( wxWindow::FindFocus() != player )
703  player->SetFocus();
704 
705  return 0;
706 }
707 
708 
709 class TERMINATE_HANDLER : public wxProcess
710 {
711 public:
712  TERMINATE_HANDLER( const wxString& appName ) :
713  m_appName( appName )
714  { }
715 
716  void OnTerminate( int pid, int status ) override
717  {
718  wxString msg = wxString::Format( _( "%s closed [pid=%d]\n" ), m_appName, pid );
719 
720  wxWindow* window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
721 
722  if( window ) // Should always happen.
723  {
724  // Be sure the kicad frame manager is found
725  // This dynamic cast is not really mandatory, but ...
726  KICAD_MANAGER_FRAME* frame = dynamic_cast<KICAD_MANAGER_FRAME*>( window );
727 
728  if( frame )
729  frame->PrintMsg( msg );
730  }
731 
732  delete this;
733  }
734 
735 private:
736  wxString m_appName;
737 };
738 
739 
741 {
742  wxString execFile;
743  wxString params;
744 
746  execFile = GERBVIEW_EXE;
747  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::convertImage ) )
748  execFile = BITMAPCONVERTER_EXE;
749  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::showCalculator ) )
750  execFile = PCB_CALCULATOR_EXE;
752  execFile = PL_EDITOR_EXE;
753  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::openTextEditor ) )
754  execFile = Pgm().GetTextEditor();
755  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherSch ) )
756  execFile = EESCHEMA_EXE;
757  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherPCB ) )
758  execFile = PCBNEW_EXE;
759 #ifdef PCM
760  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::showPluginManager ) )
761  {
762  DIALOG_PCM* pcm = new DIALOG_PCM( m_frame );
763  pcm->ShowModal();
764  pcm->Destroy();
765  }
766 #endif
767  else
768  wxFAIL_MSG( "Execute(): unexpected request" );
769 
770  if( execFile.IsEmpty() )
771  return 0;
772 
773  if( aEvent.Parameter<wxString*>() )
774  params = *aEvent.Parameter<wxString*>();
775  else if( ( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) )
776  && m_frame->IsProjectActive() )
777  params = m_frame->Prj().GetProjectPath();
778 
779  if( !params.empty() )
780  QuoteString( params );
781 
782  TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( execFile );
783 
784  long pid = ExecuteFile( execFile, params, callback );
785 
786  if( pid > 0 )
787  {
788  wxString msg = wxString::Format( _( "%s %s opened [pid=%ld]\n" ), execFile, params, pid );
789  m_frame->PrintMsg( msg );
790 
791 #ifdef __WXMAC__
792  msg.Printf( "osascript -e 'activate application \"%s\"' ", execFile );
793  system( msg.c_str() );
794 #endif
795  }
796  else
797  {
798  delete callback;
799  }
800 
801  return 0;
802 }
803 
804 
806 {
813 
816 
826 
829 
830 #ifdef PCM
831  Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::showPluginManager.MakeEvent() );
832 #endif
833 }
const std::string NetlistFileExtension
wxString AllProjectFilesWildcard()
static TOOL_ACTION newProject
void PrintMsg(const wxString &text)
KiCad executable names.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:64
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:55
int ShowPlayer(const TOOL_EVENT &aEvent)
const std::string LegacyFootprintLibPathExtension
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
const wxString PL_EDITOR_EXE
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:284
wxString LegacyProjectFileWildcard()
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:48
This file is part of the common library.
Helper widget to select whether a new directory should be created for a project.
const std::string KiCadFootprintFileExtension
const wxString PCBNEW_EXE
const std::string ProjectFileExtension
PROJECT_TEMPLATE * GetSelectedTemplate()
const std::string LegacyPcbFileExtension
const std::string LegacySymbolLibFileExtension
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
PROJECT & Prj()
Definition: kicad.cpp:403
const std::string BackupFileSuffix
static TOOL_ACTION showCalculator
static TOOL_ACTION openDemoProject
const wxString SchLegacyFileName()
static TOOL_ACTION viewGerbers
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition: gestfich.cpp:334
int OpenDemoProject(const TOOL_EVENT &aEvent)
static TOOL_ACTION newFromTemplate
const std::string SchematicSymbolFileExtension
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:382
void UpdateAll()
Run update handlers for the menu and its submenus.
void OnTerminate(int pid, int status) override
const std::string GerberFileExtension
const std::string KiCadPcbFileExtension
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:122
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).
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
bool IsProtelExtension(const wxString &ext)
const wxString GERBVIEW_EXE
static TOOL_ACTION convertImage
virtual wxDirTraverseResult OnDir(const wxString &aSrcDirPath) override
static TOOL_ACTION closeProject
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:88
int Refresh(const TOOL_EVENT &aEvent)
static TOOL_ACTION editOtherPCB
SAVE_AS_TRAVERSER(KICAD_MANAGER_FRAME *aFrame, const wxString &aSrcProjectDirPath, const wxString &aSrcProjectName, const wxString &aNewProjectDirPath, const wxString &aNewProjectName)
wxString GetMruPath() const
const std::string FootprintAssignmentFileExtension
const wxString SchFileName()
const wxString EESCHEMA_EXE
void QuoteString(wxString &string)
Add un " to the start and the end of string (if not already done).
Definition: gestfich.cpp:42
static TOOL_ACTION editSchematic
int OpenProject(const TOOL_EVENT &aEvent)
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
int ExecuteFile(const wxString &ExecFile, const wxString &param, wxProcess *callback)
Call the executable file ExecFile with the command line parameters param.
Definition: gestfich.cpp:115
TERMINATE_HANDLER(const wxString &appName)
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Implementing pcm main dialog.
Definition: dialog_pcm.h:35
KICAD_MANAGER_FRAME * m_frame
< Pointer to the currently used edit/draw frame.
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:432
const std::string LegacySymbolDocumentFileExtension
Generic, UI-independent tool event.
Definition: tool_event.h:152
DIR_CHECKBOX(wxWindow *aParent)
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
const wxString PCB_CALCULATOR_EXE
static TOOL_ACTION editFootprints
#define _(s)
pcbnew DSO
Definition: kiway.h:269
static TOOL_ACTION updateMenu
Definition: actions.h:167
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:195
int NewProject(const TOOL_EVENT &aEvent)
int SaveProjectAs(const TOOL_EVENT &aEvent)
const std::string LegacySchematicFileExtension
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:208
int CloseProject(const TOOL_EVENT &aEvent)
wxCheckBox * m_cbCreateDir
void CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
wxString ProjectFileWildcard()
eeschema DSO
Definition: kiway.h:268
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
bool CloseProject(bool aSave)
Closes the project, and saves it if aSave is true;.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
static TOOL_ACTION editOtherSch
KICAD_MANAGER_FRAME * m_frame
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.
static TOOL_ACTION editPCB
int UpdateMenu(const TOOL_EVENT &aEvent)
const std::string DrawingSheetFileExtension
see class PGM_BASE
bool CreateProject(wxFileName &aNewProjectPath, wxString *aErrorMsg=nullptr)
Copies and renames all template files to create a new project.
const wxString PcbLegacyFileName()
static TOOL_ACTION openProject
static TOOL_ACTION saveAs
Definition: actions.h:52
#define KICAD_MANAGER_FRAME_NAME
static TOOL_ACTION zoomRedraw
Definition: actions.h:90
static wxString GetStockDemosPath()
Gets the stock (install) demos path.
Definition: paths.cpp:252
static wxWindow * Create(wxWindow *aParent)
const wxString PcbFileName()
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:148
int NewFromTemplate(const TOOL_EVENT &aEvent)
const std::string KiCadSchematicFileExtension
void AddTemplatesPage(const wxString &aTitle, wxFileName &aPath)
Add a new page with aTitle, populated with templates from aPath.
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:77
int ShowModal() override
Definition: confirm.cpp:99
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:128
int openProject(const wxString &aDefaultDir)
void LoadProject(const wxFileName &aProjectFileName)
const wxString BITMAPCONVERTER_EXE
std::map< wxString, ENV_VAR_ITEM >::const_iterator ENV_VAR_MAP_CITER
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:299
static TOOL_ACTION editSymbols
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:315
The main KiCad project manager frame.
int Execute(const TOOL_EVENT &aEvent)
Set up handlers for various events.
static TOOL_ACTION openTextEditor
static TOOL_ACTION editDrawingSheet
const std::string DrillFileExtension
bool CreateNewDir() const
const std::string KiCadSymbolLibFileExtension
virtual wxDirTraverseResult OnFile(const wxString &aSrcFilePath) override