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 <wx/checkbox.h>
34 #include <wx/dir.h>
35 #include <wx/filedlg.h>
36 
37 
39 class DIR_CHECKBOX : public wxPanel
40 {
41 public:
42  DIR_CHECKBOX( wxWindow* aParent )
43  : wxPanel( aParent )
44  {
45  m_cbCreateDir = new wxCheckBox( this, wxID_ANY,
46  _( "Create a new folder for the project" ) );
47  m_cbCreateDir->SetValue( true );
48 
49  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
50  sizer->Add( m_cbCreateDir, 0, wxALL, 8 );
51 
52  SetSizerAndFit( sizer );
53  }
54 
55  bool CreateNewDir() const
56  {
57  return m_cbCreateDir->GetValue();
58  }
59 
60  static wxWindow* Create( wxWindow* aParent )
61  {
62  return new DIR_CHECKBOX( aParent );
63  }
64 
65 protected:
66  wxCheckBox* m_cbCreateDir;
67 };
68 
69 
71  TOOL_INTERACTIVE( "kicad.Control" ),
72  m_frame( nullptr )
73 {
74 }
75 
76 
78 {
79  m_frame = getEditFrame<KICAD_MANAGER_FRAME>();
80 }
81 
82 
84 {
85  wxString default_dir = m_frame->GetMruPath();
86  wxFileDialog dlg( m_frame, _( "Create New Project" ), default_dir, wxEmptyString,
87  ProjectFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
88 
89  // Add a "Create a new directory" checkbox
90  dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
91 
92  if( dlg.ShowModal() == wxID_CANCEL )
93  return -1;
94 
95  wxFileName pro( dlg.GetPath() );
96 
97  // wxFileName automatically extracts an extension. But if it isn't
98  // a .pro extension, we should keep it as part of the filename
99  if( !pro.GetExt().IsEmpty() && pro.GetExt().ToStdString() != ProjectFileExtension )
100  pro.SetName( pro.GetName() + wxT( "." ) + pro.GetExt() );
101 
102  pro.SetExt( ProjectFileExtension ); // enforce extension
103 
104  if( !pro.IsAbsolute() )
105  pro.MakeAbsolute();
106 
107  // Append a new directory with the same name of the project file.
108  if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
109  pro.AppendDir( pro.GetName() );
110 
111  // Check if the project directory is empty if it already exists.
112  wxDir directory( pro.GetPath() );
113 
114  if( !pro.DirExists() )
115  {
116  if( !pro.Mkdir() )
117  {
118  wxString msg;
119  msg.Printf( _( "Folder '%s' could not be created.\n\n"
120  "Make sure you have write permissions and try again." ),
121  pro.GetPath() );
123  return -1;
124  }
125  }
126  else if( directory.HasFiles() )
127  {
128  wxString msg = _( "The selected folder is not empty. It is recommended that you "
129  "create projects in their own empty folder.\n\n"
130  "Do you want to continue?" );
131 
132  if( !IsOK( m_frame, msg ) )
133  return -1;
134  }
135 
136  m_frame->CreateNewProject( pro );
137  m_frame->LoadProject( pro );
138 
139  return 0;
140 }
141 
142 
144 {
146 
147  wxFileName templatePath;
148  wxString envStr;
149 
150  // KiCad system template path.
151  ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD6_TEMPLATE_DIR" );
152 
153  if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
154  {
155  templatePath.AssignDir( it->second.GetValue() );
156  ps->AddTemplatesPage( _( "System Templates" ), templatePath );
157  }
158 
159  // User template path.
160  it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" );
161 
162  if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
163  {
164  templatePath.AssignDir( it->second.GetValue() );
165  ps->AddTemplatesPage( _( "User Templates" ), templatePath );
166  }
167 
168  // Show the project template selector dialog
169  if( ps->ShowModal() != wxID_OK )
170  return -1;
171 
172  if( !ps->GetSelectedTemplate() )
173  {
174  wxMessageBox( _( "No project template was selected. Cannot generate new project." ),
175  _( "Error" ), wxOK | wxICON_ERROR, m_frame );
176 
177  return -1;
178  }
179 
180  // Get project destination folder and project file name.
181  wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
182  wxString title = _( "New Project Folder" );
183  wxFileDialog dlg( m_frame, title, default_dir, wxEmptyString, ProjectFileWildcard(),
184  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
185 
186  // Add a "Create a new directory" checkbox
187  dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
188 
189  if( dlg.ShowModal() == wxID_CANCEL )
190  return -1;
191 
192  wxFileName fn( dlg.GetPath() );
193 
194  // wxFileName automatically extracts an extension. But if it isn't a .kicad_pro extension,
195  // we should keep it as part of the filename
196  if( !fn.GetExt().IsEmpty() && fn.GetExt().ToStdString() != ProjectFileExtension )
197  fn.SetName( fn.GetName() + wxT( "." ) + fn.GetExt() );
198 
199  fn.SetExt( ProjectFileExtension );
200 
201  if( !fn.IsAbsolute() )
202  fn.MakeAbsolute();
203 
204  // Append a new directory with the same name of the project file.
205  if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
206  fn.AppendDir( fn.GetName() );
207 
208  // Check if the project directory is empty if it already exists.
209  wxDir directory( fn.GetPath() );
210 
211  if( !fn.DirExists() )
212  {
213  if( !fn.Mkdir() )
214  {
215  wxString msg;
216  msg.Printf( _( "Folder '%s' could not be created.\n\n"
217  "Make sure you have write permissions and try again." ),
218  fn.GetPath() );
220  return -1;
221  }
222  }
223 
224  if( !fn.IsDirWritable() )
225  {
226  wxString msg;
227 
228  msg.Printf( _( "Cannot write to folder '%s'." ), fn.GetPath() );
229  wxMessageDialog msgDlg( m_frame, msg, _( "Error" ), wxICON_ERROR | wxOK | wxCENTER );
230  msgDlg.SetExtendedMessage( _( "Make sure you have write permissions and try again." ) );
231  msgDlg.ShowModal();
232  return -1;
233  }
234 
235  // Make sure we are not overwriting anything in the destination folder.
236  std::vector< wxFileName > destFiles;
237 
238  if( ps->GetSelectedTemplate()->GetDestinationFiles( fn, destFiles ) )
239  {
240  std::vector< wxFileName > overwrittenFiles;
241 
242  for( const auto& file : destFiles )
243  {
244  if( file.FileExists() )
245  overwrittenFiles.push_back( file );
246  }
247 
248  if( !overwrittenFiles.empty() )
249  {
250  wxString extendedMsg = _( "Overwriting files:" ) + "\n";
251 
252  for( const auto& file : overwrittenFiles )
253  extendedMsg += "\n" + file.GetFullName();
254 
255  KIDIALOG msgDlg( m_frame, _( "Similar files already exist in the destination folder." ),
256  _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
257  msgDlg.SetExtendedMessage( extendedMsg );
258  msgDlg.SetOKLabel( _( "Overwrite" ) );
259  msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
260 
261  if( msgDlg.ShowModal() == wxID_CANCEL )
262  return -1;
263  }
264  }
265 
266  wxString errorMsg;
267 
268  // The selected template widget contains the template we're attempting to use to
269  // create a project
270  if( !ps->GetSelectedTemplate()->CreateProject( fn, &errorMsg ) )
271  {
272  wxMessageDialog createDlg( m_frame,
273  _( "A problem occurred creating new project from template." ),
274  _( "Error" ),
275  wxOK | wxICON_ERROR );
276 
277  if( !errorMsg.empty() )
278  createDlg.SetExtendedMessage( errorMsg );
279 
280  createDlg.ShowModal();
281  return -1;
282  }
283 
284  m_frame->CreateNewProject( fn.GetFullPath() );
285  m_frame->LoadProject( fn );
286  return 0;
287 }
288 
289 
291 {
292  wxString wildcard = AllProjectFilesWildcard() + "|" + ProjectFileWildcard() + "|"
294 
295  wxString default_dir = m_frame->GetMruPath();
296  wxFileDialog dlg( m_frame, _( "Open Existing Project" ), default_dir, wxEmptyString,
297  wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
298 
299  if( dlg.ShowModal() == wxID_CANCEL )
300  return -1;
301 
302  wxFileName pro( dlg.GetPath() );
303 
304  if( !pro.IsAbsolute() )
305  pro.MakeAbsolute();
306 
307  if( !pro.FileExists() )
308  return -1;
309 
310  m_frame->LoadProject( pro );
311  return 0;
312 }
313 
314 
316 {
317  m_frame->CloseProject( true );
318  return 0;
319 }
320 
321 
322 class SAVE_AS_TRAVERSER : public wxDirTraverser
323 {
324 public:
326  const wxString& aSrcProjectDirPath,
327  const wxString& aSrcProjectName,
328  const wxString& aNewProjectDirPath,
329  const wxString& aNewProjectName ) :
330  m_frame( aFrame ),
331  m_projectDirPath( aSrcProjectDirPath ),
332  m_projectName( aSrcProjectName ),
333  m_newProjectDirPath( aNewProjectDirPath ),
334  m_newProjectName( aNewProjectName )
335  {
336  }
337 
338  virtual wxDirTraverseResult OnFile( const wxString& aSrcFilePath ) override
339  {
340  // Recursion guard for a Save As to a location inside the source project.
341  if( aSrcFilePath.StartsWith( m_newProjectDirPath ) )
342  return wxDIR_CONTINUE;
343 
344  wxFileName destFile( aSrcFilePath );
345  wxString ext = destFile.GetExt();
346  bool atRoot = destFile.GetPath() == m_projectDirPath;
347 
348  if( ext == "pro" )
349  {
350  wxString destPath = destFile.GetPath();
351 
352  if( destPath.StartsWith( m_projectDirPath ) )
353  {
354  destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
355  destFile.SetPath( destPath );
356  }
357 
358  if( destFile.GetName() == m_projectName )
359  {
360  destFile.SetName( m_newProjectName );
361 
362  if( atRoot )
363  m_newProjectFile = destFile;
364  }
365 
366  // Currently all paths in the settings file are relative, so we can just do a
367  // straight copy
368  KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
369  }
370  else if( ext == KiCadSchematicFileExtension
378  || ext == NetlistFileExtension
379  || destFile.GetName() == "sym-lib-table" )
380  {
383  m_newProjectName, aSrcFilePath, m_errors );
384  }
385  else if( ext == KiCadPcbFileExtension
387  || ext == LegacyPcbFileExtension
391  || destFile.GetName() == "fp-lib-table" )
392  {
395  m_newProjectName, aSrcFilePath, m_errors );
396  }
397  else if( ext == DrawingSheetFileExtension )
398  {
399  KIFACE* pleditor = m_frame->Kiway().KiFACE( KIWAY::FACE_PL_EDITOR );
401  m_newProjectName, aSrcFilePath, m_errors );
402  }
403  else if( ext == GerberFileExtension
404  || ext == GerberJobFileExtension
405  || ext == DrillFileExtension
406  || IsProtelExtension( ext ) )
407  {
408  KIFACE* gerbview = m_frame->Kiway().KiFACE( KIWAY::FACE_GERBVIEW );
410  m_newProjectName, aSrcFilePath, m_errors );
411  }
412  else
413  {
414  // Everything we don't recognize just gets a straight copy.
415  wxString destPath = destFile.GetPathWithSep();
416  wxString destName = destFile.GetName();
417  wxUniChar pathSep = wxFileName::GetPathSeparator();
418 
419  wxString srcProjectFootprintLib = pathSep + m_projectName + ".pretty" + pathSep;
420  wxString newProjectFootprintLib = pathSep + m_newProjectName + ".pretty" + pathSep;
421 
422  if( destPath.StartsWith( m_projectDirPath ) )
423  {
424  destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
425  destFile.SetPath( destPath );
426  }
427 
428  if( destName == m_projectName )
429  destFile.SetName( m_newProjectName );
430 
431  destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib, true );
432  destFile.SetPath( destPath );
433 
434 
435  KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
436  }
437 
438  return wxDIR_CONTINUE;
439  }
440 
441  virtual wxDirTraverseResult OnDir( const wxString& aSrcDirPath ) override
442  {
443  // Recursion guard for a Save As to a location inside the source project.
444  if( aSrcDirPath.StartsWith( m_newProjectDirPath ) )
445  return wxDIR_CONTINUE;
446 
447  wxFileName destDir( aSrcDirPath );
448  wxString destDirPath = destDir.GetPathWithSep();
449  wxUniChar pathSep = wxFileName::GetPathSeparator();
450 
451  if( destDirPath.StartsWith( m_projectDirPath + pathSep ) )
452  {
453  destDirPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
454  destDir.SetPath( destDirPath );
455  }
456 
457  if( destDir.GetName() == m_projectName )
458  {
459  if( destDir.GetExt() == "pretty" )
460  destDir.SetName( m_newProjectName );
461 #if 0
462  // WAYNE STAMBAUGH TODO:
463  // If we end up with a symbol equivalent to ".pretty" we'll want to handle it here....
464  else if( destDir.GetExt() == "sym_lib_dir_extension" )
465  destDir.SetName( m_newProjectName );
466 #endif
467  }
468 
469  if( !wxMkdir( destDir.GetFullPath() ) )
470  {
471  wxString msg;
472 
473  if( !m_errors.empty() )
474  m_errors += "\n";
475 
476  msg.Printf( _( "Cannot copy folder '%s'." ), destDir.GetFullPath() );
477  m_errors += msg;
478  }
479 
480  return wxDIR_CONTINUE;
481  }
482 
483  wxString GetErrors() { return m_errors; }
484 
485  wxFileName GetNewProjectFile() { return m_newProjectFile; }
486 
487 private:
489 
491  wxString m_projectName;
494 
495  wxFileName m_newProjectFile;
496  wxString m_errors;
497 };
498 
499 
501 {
502  wxString msg;
503 
504  wxFileName currentProjectFile( Prj().GetProjectFullName() );
505  wxString currentProjectDirPath = currentProjectFile.GetPath();
506  wxString currentProjectName = Prj().GetProjectName();
507 
508  wxString default_dir = m_frame->GetMruPath();
509 
510  if( default_dir == currentProjectDirPath
511  || default_dir == currentProjectDirPath + wxFileName::GetPathSeparator() )
512  {
513  // Don't start within the current project
514  wxFileName default_dir_fn( default_dir );
515  default_dir_fn.RemoveLastDir();
516  default_dir = default_dir_fn.GetPath();
517  }
518 
519  wxFileDialog dlg( m_frame, _( "Save Project To" ), default_dir, wxEmptyString, wxEmptyString,
520  wxFD_SAVE );
521 
522  if( dlg.ShowModal() == wxID_CANCEL )
523  return -1;
524 
525  wxFileName newProjectDir( dlg.GetPath() );
526 
527  if( !newProjectDir.IsAbsolute() )
528  newProjectDir.MakeAbsolute();
529 
530  if( wxDirExists( newProjectDir.GetFullPath() ) )
531  {
532  msg.Printf( _( "'%s' already exists." ), newProjectDir.GetFullPath() );
534  return -1;
535  }
536 
537  if( !wxMkdir( newProjectDir.GetFullPath() ) )
538  {
539  msg.Printf( _( "Directory '%s' could not be created.\n\n"
540  "Please make sure you have write permissions and try again." ),
541  newProjectDir.GetPath() );
543  return -1;
544  }
545 
546  if( !newProjectDir.IsDirWritable() )
547  {
548  msg.Printf( _( "Cannot write to folder '%s'." ), newProjectDir.GetFullPath() );
549  wxMessageDialog msgDlg( m_frame, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
550  msgDlg.SetExtendedMessage( _( "Please check your access permissions to this folder "
551  "and try again." ) );
552  msgDlg.ShowModal();
553  return -1;
554  }
555 
556  const wxString& newProjectDirPath = newProjectDir.GetFullPath();
557  const wxString& newProjectName = newProjectDir.GetName();
558  wxDir currentProjectDir( currentProjectDirPath );
559 
560  SAVE_AS_TRAVERSER traverser( m_frame, currentProjectDirPath, currentProjectName,
561  newProjectDirPath, newProjectName );
562 
563  currentProjectDir.Traverse( traverser );
564 
565  if( !traverser.GetErrors().empty() )
566  DisplayErrorMessage( m_frame, traverser.GetErrors() );
567 
568  if( traverser.GetNewProjectFile().FileExists() )
569  {
571  m_frame->LoadProject( traverser.GetNewProjectFile() );
572  }
573 
574  return 0;
575 }
576 
577 
579 {
581  return 0;
582 }
583 
584 
586 {
587  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
588  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
589  SELECTION dummySel;
590 
591  if( conditionalMenu )
592  conditionalMenu->Evaluate( dummySel );
593 
594  if( actionMenu )
595  actionMenu->UpdateAll();
596 
597  return 0;
598 }
599 
600 
602 {
603  FRAME_T playerType = aEvent.Parameter<FRAME_T>();
604  KIWAY_PLAYER* player;
605 
606  if( playerType == FRAME_SCH && !m_frame->IsProjectActive() )
607  {
608  DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a schematic." ),
609  wxEmptyString );
610  return -1;
611  }
612  else if( playerType == FRAME_PCB_EDITOR && !m_frame->IsProjectActive() )
613  {
614  DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a pcb." ),
615  wxEmptyString );
616  return -1;
617  }
618 
619  // Prevent multiple KIWAY_PLAYER loading at one time
620  if( !m_loading.try_lock() )
621  return -1;
622 
623  const std::lock_guard<std::mutex> lock( m_loading, std::adopt_lock );
624 
625  try
626  {
627  player = m_frame->Kiway().Player( playerType, true );
628  }
629  catch( const IO_ERROR& err )
630  {
631  wxMessageBox( _( "Application failed to load:\n" ) + err.What(), _( "KiCad Error" ),
632  wxOK | wxICON_ERROR, m_frame );
633  return -1;
634  }
635 
636  if ( !player )
637  {
638  wxMessageBox( _( "Application failed to load." ), _( "KiCad Error" ),
639  wxOK | wxICON_ERROR, m_frame );
640  return -1;
641  }
642 
643  if( !player->IsVisible() ) // A hidden frame might not have the document loaded.
644  {
645  wxString filepath;
646 
647  if( playerType == FRAME_SCH )
648  {
649  wxFileName kicad_schematic( m_frame->SchFileName() );
650  wxFileName legacy_schematic( m_frame->SchLegacyFileName() );
651 
652  if( !legacy_schematic.FileExists() || kicad_schematic.FileExists() )
653  filepath = kicad_schematic.GetFullPath();
654  else
655  filepath = legacy_schematic.GetFullPath();
656  }
657  else if( playerType == FRAME_PCB_EDITOR )
658  {
659  wxFileName kicad_board( m_frame->PcbFileName() );
660  wxFileName legacy_board( m_frame->PcbLegacyFileName() );
661 
662  if( !legacy_board.FileExists() || kicad_board.FileExists() )
663  filepath = kicad_board.GetFullPath();
664  else
665  filepath = legacy_board.GetFullPath();
666  }
667 
668  if( !filepath.IsEmpty() )
669  {
670  if( !player->OpenProjectFiles( std::vector<wxString>( 1, filepath ) ) )
671  return -1;
672  }
673 
674  player->Show( true );
675  }
676 
677  // Needed on Windows, other platforms do not use it, but it creates no issue
678  if( player->IsIconized() )
679  player->Iconize( false );
680 
681  player->Raise();
682 
683  // Raising the window does not set the focus on Linux. This should work on
684  // any platform.
685  if( wxWindow::FindFocus() != player )
686  player->SetFocus();
687 
688  return 0;
689 }
690 
691 
692 class TERMINATE_HANDLER : public wxProcess
693 {
694 public:
695  TERMINATE_HANDLER( const wxString& appName ) :
696  m_appName( appName )
697  { }
698 
699  void OnTerminate( int pid, int status ) override
700  {
701  wxString msg = wxString::Format( _( "%s closed [pid=%d]\n" ), m_appName, pid );
702 
703  wxWindow* window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
704 
705  if( window ) // Should always happen.
706  {
707  // Be sure the kicad frame manager is found
708  // This dynamic cast is not really mandatory, but ...
709  KICAD_MANAGER_FRAME* frame = dynamic_cast<KICAD_MANAGER_FRAME*>( window );
710 
711  if( frame )
712  frame->PrintMsg( msg );
713  }
714 
715  delete this;
716  }
717 
718 private:
719  wxString m_appName;
720 };
721 
722 
724 {
725  wxString execFile;
726  wxString params;
727 
729  execFile = GERBVIEW_EXE;
730  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::convertImage ) )
731  execFile = BITMAPCONVERTER_EXE;
732  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::showCalculator ) )
733  execFile = PCB_CALCULATOR_EXE;
735  execFile = PL_EDITOR_EXE;
736  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::openTextEditor ) )
737  execFile = Pgm().GetEditorName();
738  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherSch ) )
739  execFile = EESCHEMA_EXE;
740  else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherPCB ) )
741  execFile = PCBNEW_EXE;
742  else
743  wxFAIL_MSG( "Execute(): unexpected request" );
744 
745  if( execFile.IsEmpty() )
746  return 0;
747 
748  if( aEvent.Parameter<wxString*>() )
749  params = *aEvent.Parameter<wxString*>();
750  else if( ( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) )
751  && m_frame->IsProjectActive() )
752  params = m_frame->Prj().GetProjectPath();
753 
754  if( !params.empty() )
755  AddDelimiterString( params );
756 
757  TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( execFile );
758 
759  long pid = ExecuteFile( m_frame, execFile, params, callback );
760 
761  if( pid > 0 )
762  {
763  wxString msg = wxString::Format( _( "%s %s opened [pid=%ld]\n" ), execFile, params, pid );
764  m_frame->PrintMsg( msg );
765 
766 #ifdef __WXMAC__
767  msg.Printf( "osascript -e 'activate application \"%s\"' ", execFile );
768  system( msg.c_str() );
769 #endif
770  }
771  else
772  {
773  delete callback;
774  }
775 
776  return 0;
777 }
778 
779 
781 {
787 
790 
800 
803 }
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:265
This file is part of the common library TODO brief description.
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
const wxString SchLegacyFileName()
static TOOL_ACTION viewGerbers
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition: gestfich.cpp:363
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:373
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:123
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
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
TERMINATE_HANDLER(const wxString &appName)
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
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:427
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:267
void AddDelimiterString(wxString &string)
Add un " to the start and the end of string (if not already done).
Definition: gestfich.cpp:42
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:192
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:206
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:266
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 wxWindow * Create(wxWindow *aParent)
const wxString PcbFileName()
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:146
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:129
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:280
static TOOL_ACTION editSymbols
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString &param, wxProcess *callback)
Call the executable file ExecFile with the command line parameters param.
Definition: gestfich.cpp:165
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:296
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