void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName, bool aTemplateSelector = false ) { wxFileName newProjectName = aPrjFullFileName; wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string. ClearMsg(); // If we are creating a project from a template, make sure the template directory is sane if( aTemplateSelector ) { DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this ); wxFileName templatePath; wxString envStr; #ifndef __WXMAC__ wxGetEnv( wxT( "KICAD" ), &envStr ); // Add a new tab for system templates if( !envStr.empty() ) { // user may or may not have including terminating separator. if( !envStr.EndsWith( sep ) ) envStr += sep; templatePath = envStr + wxT( "template" ) + sep; } else { // The standard path should be in the share directory for kicad. As // it is normal on Windows to only have the share directory and not // the kicad sub-directory we fall back to that if the directory // doesn't exist templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) + sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "kicad" ) + sep + wxT( "template" ) + sep; if( !wxDirExists( templatePath.GetFullPath() ) ) { templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) + sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "template" ) + sep; } } #else // Use what is provided in the bundle data dir templatePath = GetOSXKicadDataDir() + sep + wxT( "template" ); #endif ps->AddTemplatesPage( _( "System Templates" ), templatePath ); // Add a new tab for user templates wxFileName userPath = wxStandardPaths::Get().GetDocumentsDir() + sep + wxT( "kicad" ) + sep + wxT( "template" ) + sep; ps->AddTemplatesPage( _( "User Templates" ), userPath ); // Check to see if a custom template location is available and setup a // new selection tab if there is. envStr.clear(); wxGetEnv( wxT( "KICAD_PTEMPLATES" ), &envStr ); if( !envStr.empty() ) { if( !envStr.EndsWith( sep ) ) envStr += sep; wxFileName envPath = envStr; ps->AddTemplatesPage( _( "Portable Templates" ), envPath ); } // Show the project template selector dialog int result = ps->ShowModal(); if( ( result != wxID_OK ) || ( ps->GetSelectedTemplate() == NULL ) ) { if( ps->GetSelectedTemplate() == NULL ) { wxMessageBox( _( "No project template was selected. Cannot generate new " "project." ), _( "Error" ), wxOK | wxICON_ERROR, this ); } } else { // The selected template widget contains the template we're attempting to use to // create a project if( !ps->GetSelectedTemplate()->CreateProject( newProjectName ) ) { wxMessageBox( _( "Problem whilst creating new project from template!" ), _( "Template Error" ), wxOK | wxICON_ERROR, this ); } } } // Init project filename SetProjectFileName( newProjectName.GetFullPath() ); // Write settings to project file // was: wxGetApp().WriteProjectConfig( aPrjFullFileName, GeneralGroupName, s_KicadManagerParams ); Prj().ConfigSave( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams ); // Ensure a "stub" for a schematic root sheet and a board exist. // It will avoid messages from the schematic editor or the board editor to create a new file // And forces the user to create main files under the right name for the project manager wxFileName fn( newProjectName.GetFullPath() ); fn.SetExt( SchematicFileExtension ); // If a <project>.sch file does not exist, create a "stub" file if( !fn.FileExists() ) { wxFile file( fn.GetFullPath(), wxFile::write ); if( file.IsOpened() ) file.Write( wxT( "EESchema Schematic File Version 2\n" ) ); // wxFile dtor will close the file } // If a <project>.kicad_pcb or <project>.brd file does not exist, // create a .kicad_pcb "stub" file fn.SetExt( KiCadPcbFileExtension ); wxFileName leg_fn( fn ); leg_fn.SetExt( LegacyPcbFileExtension ); if( !fn.FileExists() && !leg_fn.FileExists() ) { wxFile file( fn.GetFullPath(), wxFile::write ); if( file.IsOpened() ) file.Write( wxT( "(kicad_pcb (version 4) (host kicad \"dummy file\") )\n" ) ); // wxFile dtor will close the file } // Enable the toolbar and menubar buttons and clear the help text. m_active_project = true; m_MessagesBox->Clear(); }
void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event ) { DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this ); wxFileName templatePath; wxString envStr; // KiCad system template path. ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD_TEMPLATE_DIR" ); if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) { templatePath.AssignDir( it->second.GetValue() ); ps->AddTemplatesPage( _( "System Templates" ), templatePath ); } // User template path. it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" ); if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) { templatePath.AssignDir( it->second.GetValue() ); ps->AddTemplatesPage( _( "User Templates" ), templatePath ); } // Show the project template selector dialog if( ps->ShowModal() != wxID_OK ) return; if( ps->GetSelectedTemplate() == NULL ) { wxMessageBox( _( "No project template was selected. Cannot generate new project." ), _( "Error" ), wxOK | wxICON_ERROR, this ); return; } // Get project destination folder and project file name. wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep(); wxString title = _( "New Project Folder" ); wxFileDialog dlg( this, title, default_dir, wxEmptyString, ProjectFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); // Add a "Create a new directory" checkbox dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create ); if( dlg.ShowModal() == wxID_CANCEL ) return; wxFileName fn( dlg.GetPath() ); // wxFileName automatically extracts an extension. But if it isn't // a .pro extension, we should keep it as part of the filename if( !fn.GetExt().IsEmpty() && fn.GetExt().ToStdString() != ProjectFileExtension ) fn.SetName( fn.GetName() + wxT( "." ) + fn.GetExt() ); fn.SetExt( ProjectFileExtension ); // enforce extension if( !fn.IsAbsolute() ) fn.MakeAbsolute(); // Append a new directory with the same name of the project file. if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() ) fn.AppendDir( fn.GetName() ); // Check if the project directory is empty if it already exists. wxDir directory( fn.GetPath() ); if( !fn.DirExists() ) { if( !fn.Mkdir() ) { wxString msg; msg.Printf( _( "Directory \"%s\" could not be created.\n\n" "Please make sure you have write permissions and try again." ), fn.GetPath() ); DisplayErrorMessage( this, msg ); return; } } if( !fn.IsDirWritable() ) { wxString msg; msg.Printf( _( "Cannot write to folder \"%s\"." ), fn.GetPath() ); wxMessageDialog msgDlg( this, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER ); msgDlg.SetExtendedMessage( _( "Please check your access permissions to this folder " "and try again." ) ); msgDlg.ShowModal(); return; } ClearMsg(); // Make sure we are not overwriting anything in the destination folder. std::vector< wxFileName > destFiles; if( ps->GetSelectedTemplate()->GetDestinationFiles( fn, destFiles ) ) { std::vector< wxFileName > overwrittenFiles; for( const auto& file : destFiles ) { if( file.FileExists() ) overwrittenFiles.push_back( file ); } if( !overwrittenFiles.empty() ) { wxString extendedMsg = _( "Overwriting files:" ) + "\n"; for( const auto& file : overwrittenFiles ) extendedMsg += "\n" + file.GetFullName(); KIDIALOG msgDlg( this, _( "Similar files already exist in the destination folder." ), _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); msgDlg.SetExtendedMessage( extendedMsg ); msgDlg.SetOKLabel( _( "Overwrite" ) ); msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ ); if( msgDlg.ShowModal() == wxID_CANCEL ) return; } } wxString errorMsg; // The selected template widget contains the template we're attempting to use to // create a project if( !ps->GetSelectedTemplate()->CreateProject( fn, &errorMsg ) ) { wxMessageDialog createDlg( this, _( "A problem occurred creating new project from template!" ), _( "Template Error" ), wxOK | wxICON_ERROR ); if( !errorMsg.empty() ) createDlg.SetExtendedMessage( errorMsg ); createDlg.ShowModal(); return; } CreateNewProject( fn.GetFullPath() ); LoadProject( fn ); }