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