Prevent KiCad from overwriting existing files with template files.

Add tests to check for existing files before copying template files.

Split load project, create new project, create new project from template,
and load project from history command events into simple methods that
perform the correct actions before loading the project.  This greatly
simplifies the code.

Create a load project method that can be called from the event handlers
above.  This simplified a lot of duplicate code that existed in many of
these event handlers.

Remove the dummy "noname.pro" file creation which created required some
ugly code to prevent this file from being created unexpectedly.  Now
KiCad launches without setting a project file name when appropriate.

Fixes lp:1713951

https://bugs.launchpad.net/kicad/+bug/1713951
This commit is contained in:
Wayne Stambaugh 2017-08-31 11:15:20 -04:00
parent eec1366ead
commit 525e04ce75
8 changed files with 410 additions and 365 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2015 Jean-Pierre Charras * Copyright (C) 2004-2015 Jean-Pierre Charras
* Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -46,24 +46,12 @@
void KICAD_MANAGER_FRAME::OnFileHistory( wxCommandEvent& event ) void KICAD_MANAGER_FRAME::OnFileHistory( wxCommandEvent& event )
{ {
wxString fn = GetFileFromHistory( event.GetId(), wxFileName projFileName = GetFileFromHistory( event.GetId(), _( "KiCad project file" ),
_( "KiCad project file" ), &PgmTop().GetFileHistory() ); &PgmTop().GetFileHistory() );
if( !projFileName.FileExists() )
return;
if( fn.size() ) LoadProject( projFileName );
{
// Any open KIFACE's must be closed before changing the project.
// We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project,
// and then break one project.
// Remember when saving files, the full path is build from the current project path
// User is prompted here to close those KIWAY_PLAYERs:
if( !Kiway.PlayersClose( false ) )
return;
// We can now set the new project filename and load this project
SetProjectFileName( fn );
wxCommandEvent cmd( 0, wxID_ANY );
OnLoadProject( cmd );
}
} }
@ -74,13 +62,13 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event )
fn.SetExt( ZipFileExtension ); fn.SetExt( ZipFileExtension );
wxFileDialog zipfiledlg( this, _( "Unzip Project" ), fn.GetPath(), wxFileDialog zipfiledlg( this, _( "Unzip Project" ), fn.GetPath(),
fn.GetFullName(), ZipFileWildcard, fn.GetFullName(), ZipFileWildcard,
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( zipfiledlg.ShowModal() == wxID_CANCEL ) if( zipfiledlg.ShowModal() == wxID_CANCEL )
return; return;
wxString msg = wxString::Format( _("\nOpen '%s'\n" ), GetChars( zipfiledlg.GetPath() ) ); wxString msg = wxString::Format( _( "\nOpen '%s'\n" ), GetChars( zipfiledlg.GetPath() ) );
PrintMsg( msg ); PrintMsg( msg );
wxDirDialog dirDlg( this, _( "Target Directory" ), fn.GetPath(), wxDirDialog dirDlg( this, _( "Target Directory" ), fn.GetPath(),
@ -178,7 +166,8 @@ void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event )
if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
{ {
wxMessageBox( wxString::Format( _( "Unable to create zip archive file '%s'" ), zipfilename ) ); wxMessageBox( wxString::Format( _( "Unable to create zip archive file '%s'" ),
zipfilename ) );
return; return;
} }

View File

@ -98,8 +98,6 @@ bool PGM_KICAD::OnPgmInit()
SystemDirsAppend( &bases ); SystemDirsAppend( &bases );
// DBG( bases.Show( (std::string(__func__) + " bases").c_str() );)
for( unsigned i = 0; i < bases.GetCount(); ++i ) for( unsigned i = 0; i < bases.GetCount(); ++i )
{ {
wxFileName fn( bases[i], wxEmptyString ); wxFileName fn( bases[i], wxEmptyString );
@ -108,8 +106,6 @@ bool PGM_KICAD::OnPgmInit()
fn.AppendDir( wxT( "template" ) ); fn.AppendDir( wxT( "template" ) );
m_bm.m_search.AddPaths( fn.GetPath() ); m_bm.m_search.AddPaths( fn.GetPath() );
} }
//DBG( m_bm.m_search.Show( (std::string( __func__ ) + " SysSearch()").c_str() );)
} }
// Must be called before creating the main frame in order to // Must be called before creating the main frame in order to
@ -123,11 +119,12 @@ bool PGM_KICAD::OnPgmInit()
Kiway.SetTop( frame ); Kiway.SetTop( frame );
bool prjloaded = false; // true when the project is loaded wxString projToLoad;
if( App().argc > 1 ) if( App().argc > 1 )
frame->SetProjectFileName( App().argv[1] ); {
projToLoad = App().argv[1];
}
else if( GetFileHistory().GetCount() ) else if( GetFileHistory().GetCount() )
{ {
wxString last_pro = GetFileHistory().GetHistoryFile( 0 ); wxString last_pro = GetFileHistory().GetHistoryFile( 0 );
@ -135,37 +132,19 @@ bool PGM_KICAD::OnPgmInit()
if( !wxFileExists( last_pro ) ) if( !wxFileExists( last_pro ) )
{ {
GetFileHistory().RemoveFileFromHistory( 0 ); GetFileHistory().RemoveFileFromHistory( 0 );
wxFileName namelessProject( wxStandardPaths::Get().GetDocumentsDir(), NAMELESS_PROJECT,
ProjectFileExtension );
frame->SetProjectFileName( namelessProject.GetFullPath() );
} }
else else
{ {
// Try to open the last opened project, // Try to open the last opened project,
// if a project name is not given when starting Kicad // if a project name is not given when starting Kicad
frame->SetProjectFileName( last_pro ); projToLoad = last_pro;
wxCommandEvent cmd( 0, wxID_FILE1 );
frame->OnFileHistory( cmd );
prjloaded = true; // OnFileHistory() loads the project
} }
} }
else // there is no history
// Do not attempt to load a non-existent project file.
if( !projToLoad.empty() && wxFileExists( projToLoad ) )
{ {
wxFileName namelessProject( wxStandardPaths::Get().GetDocumentsDir(), NAMELESS_PROJECT, frame->LoadProject( projToLoad );
ProjectFileExtension );
frame->SetProjectFileName( namelessProject.GetFullPath() );
}
if( !prjloaded )
{
wxCommandEvent cmd( 0, wxID_ANY );
frame->OnLoadProject( cmd );
} }
frame->Show( true ); frame->Show( true );
@ -194,11 +173,9 @@ void PGM_KICAD::MacOpenFile( const wxString& aFileName )
KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) App().GetTopWindow(); KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) App().GetTopWindow();
frame->SetProjectFileName( aFileName ); if( !aFileName.empty && wxFileExists( aFileName ) )
frame->LoadProject( wxFileName( aFileName ) );
wxCommandEvent loadEvent( 0, wxID_ANY );
frame->OnLoadProject( loadEvent );
#endif #endif
} }

View File

@ -43,7 +43,7 @@ class LAUNCHER_PANEL;
class TREEPROJECTFILES; class TREEPROJECTFILES;
class TREE_PROJECT_FRAME; class TREE_PROJECT_FRAME;
// Enum to identify the type of files handled by Kicad manager // Identify the type of files handled by Kicad manager
// //
// When changing this enum please verify (and perhaps update) // When changing this enum please verify (and perhaps update)
// TREE_PROJECT_FRAME::GetFileExt(), // TREE_PROJECT_FRAME::GetFileExt(),
@ -131,14 +131,13 @@ enum id_kicad_frm {
/** /**
* Class KICAD_MANAGER_FRAME * The main KiCad project manager frame. It is not a KIWAY_PLAYER.
* is the main KiCad project manager frame. It is not a KIWAY_PLAYER.
*/ */
class KICAD_MANAGER_FRAME : public EDA_BASE_FRAME class KICAD_MANAGER_FRAME : public EDA_BASE_FRAME
{ {
public: public:
KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title, KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title,
const wxPoint& pos, const wxSize& size ); const wxPoint& pos, const wxSize& size );
~KICAD_MANAGER_FRAME(); ~KICAD_MANAGER_FRAME();
@ -146,29 +145,26 @@ public:
void OnSize( wxSizeEvent& event ); void OnSize( wxSizeEvent& event );
/** /**
* Function OnChangeIconsOptions * Select the current icons options in menus (or toolbars) in Kicad
* Selects the current icons options in menus (or toolbars) in Kicad
* (the default for toolbars/menus is 26x26 pixels, and shows icons in menus). * (the default for toolbars/menus is 26x26 pixels, and shows icons in menus).
*/ */
void OnChangeIconsOptions( wxCommandEvent& event ) override; void OnChangeIconsOptions( wxCommandEvent& event ) override;
/** /**
* Function OnLoadProject * Load an exiting project (.pro) file.
* loads an exiting or creates a new project (.pro) file.
*/ */
void OnLoadProject( wxCommandEvent& event ); void OnLoadProject( wxCommandEvent& event );
/** /**
* Function OnCreateProjectFromTemplate
* Creates a new project folder, copy a template into this new folder. * Creates a new project folder, copy a template into this new folder.
* and open this new projrct as working project * and open this new projrct as working project
*/ */
void OnCreateProjectFromTemplate( wxCommandEvent& event ); void OnCreateProjectFromTemplate( wxCommandEvent& event );
void OnNewProject( wxCommandEvent& aEvent );
/** /**
* Function OnSaveProject * Save the project (.pro) file containing the top level configuration parameters.
* is the command event hendler to Save the project (.pro) file containing the top level
* configuration parameters.
*/ */
void OnSaveProject( wxCommandEvent& event ); void OnSaveProject( wxCommandEvent& event );
@ -199,21 +195,18 @@ public:
void RecreateBaseHToolbar(); void RecreateBaseHToolbar();
/** /**
* Function PrintMsg * Displays \a aText in the text panel.
* displays \a aText in the text panel.
* *
* @param aText The text to display. * @param aText The text to display.
*/ */
void PrintMsg( const wxString& aText ); void PrintMsg( const wxString& aText );
/** /**
* a minor helper function: * Prints the current working directory name and the projet name on the text panel.
* Prints the Current Working Dir name and the projet name on the text panel.
*/ */
void PrintPrjInfo(); void PrintPrjInfo();
/** /**
* a minor helper function:
* Erase the text panel. * Erase the text panel.
*/ */
void ClearMsg(); void ClearMsg();
@ -226,15 +219,17 @@ public:
void OnUpdatePreferredPdfBrowser( wxUpdateUIEvent& event ); void OnUpdatePreferredPdfBrowser( wxUpdateUIEvent& event );
void OnUpdateRequiresProject( wxUpdateUIEvent& event ); void OnUpdateRequiresProject( wxUpdateUIEvent& event );
void CreateNewProject( const wxString& aPrjFullFileName, bool aTemplateSelector ); void CreateNewProject( const wxFileName& aProjectFileName );
void LoadProject( const wxFileName& aProjectFileName );
void LoadSettings( wxConfigBase* aCfg ) override; void LoadSettings( wxConfigBase* aCfg ) override;
void SaveSettings( wxConfigBase* aCfg ) override; void SaveSettings( wxConfigBase* aCfg ) override;
/** /**
* Function Execute * Open another KiCad application and logs a message.
* opens another KiCad application and logs a message. *
* @param frame = owner frame. * @param frame = owner frame.
* @param execFile = name of the executable file. * @param execFile = name of the executable file.
* @param param = parameters to be passed to the executable. * @param param = parameters to be passed to the executable.
@ -249,7 +244,7 @@ public:
public: public:
TERMINATE_HANDLER( const wxString& appName ) : TERMINATE_HANDLER( const wxString& appName ) :
m_appName(appName) m_appName( appName )
{ {
} }
@ -260,7 +255,7 @@ public:
* Called by sending a event with id = ID_INIT_WATCHED_PATHS * Called by sending a event with id = ID_INIT_WATCHED_PATHS
* rebuild the list of wahtched paths * rebuild the list of wahtched paths
*/ */
void OnChangeWatchedPaths(wxCommandEvent& aEvent ); void OnChangeWatchedPaths( wxCommandEvent& aEvent );
void SetProjectFileName( const wxString& aFullProjectProFileName ); void SetProjectFileName( const wxString& aFullProjectProFileName );
@ -284,7 +279,6 @@ public:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
private: private:
wxConfigBase* config() override; wxConfigBase* config() override;
const SEARCH_STACK& sys_search() override; const SEARCH_STACK& sys_search() override;

View File

@ -37,6 +37,7 @@
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <executable_names.h> #include <executable_names.h>
#include <build_version.h>
#include "pgm_kicad.h" #include "pgm_kicad.h"
#include "tree_project_frame.h" #include "tree_project_frame.h"
@ -112,6 +113,8 @@ KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent,
m_auimgr.GetPane( m_LeftWin ).BestSize(wxSize(m_leftWinWidth, -1) ); m_auimgr.GetPane( m_LeftWin ).BestSize(wxSize(m_leftWinWidth, -1) );
m_auimgr.Update(); m_auimgr.Update();
SetTitle( wxString( "KiCad " ) + GetBuildVersion() );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009-2015 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -44,7 +44,7 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow ) EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow )
// Toolbar events // Toolbar events
EVT_TOOL( ID_NEW_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject ) EVT_TOOL( ID_NEW_PROJECT, KICAD_MANAGER_FRAME::OnNewProject )
EVT_TOOL( ID_NEW_PROJECT_FROM_TEMPLATE, KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate ) EVT_TOOL( ID_NEW_PROJECT_FROM_TEMPLATE, KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate )
EVT_TOOL( ID_LOAD_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject ) EVT_TOOL( ID_LOAD_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject )
@ -68,7 +68,8 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_MENU( wxID_ABOUT, KICAD_MANAGER_FRAME::GetKicadAbout ) EVT_MENU( wxID_ABOUT, KICAD_MANAGER_FRAME::GetKicadAbout )
// Range menu events // Range menu events
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::language_change ) EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END,
KICAD_MANAGER_FRAME::language_change )
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, KICAD_MANAGER_FRAME::OnFileHistory ) EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, KICAD_MANAGER_FRAME::OnFileHistory )

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2015 Jean-Pierre Charras * Copyright (C) 2004-2015 Jean-Pierre Charras
* Copyright (C) 2004-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -31,6 +31,7 @@
#include <wx/dir.h> #include <wx/dir.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/msgdlg.h>
#include <build_version.h> #include <build_version.h>
#include <config_params.h> #include <config_params.h>
@ -56,121 +57,69 @@
PARAM_CFG_ARRAY s_KicadManagerParams; PARAM_CFG_ARRAY s_KicadManagerParams;
void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName,
bool aTemplateSelector = false ) void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
{ {
wxFileName newProjectName = aPrjFullFileName; // The project file should be valid by the time we get here or something has gone wrong.
wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string. if( !aProjectFileName.Exists() )
return;
// Any open KIFACE's must be closed if they are not part of the new project.
// (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
// User is prompted here to close those KIWAY_PLAYERs:
if( !Kiway.PlayersClose( false ) )
return;
SetTitle( wxString( "KiCad " ) + GetBuildVersion() );
// Save the project file for the currently loaded project.
if( m_active_project )
Prj().ConfigLoad( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
m_active_project = true;
ClearMsg(); ClearMsg();
SetProjectFileName( aProjectFileName.GetFullPath() );
Prj().ConfigLoad( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
// If we are creating a project from a template, make sure the template directory is sane wxString title = GetTitle() + " " + aProjectFileName.GetFullPath();
if( aTemplateSelector )
{
DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this );
wxFileName templatePath; if( !aProjectFileName.IsDirWritable() )
wxString envStr; title += _( " [Read Only]" );
else
SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why?
#ifndef __WXMAC__ SetTitle( title );
wxGetEnv( wxT( "KICAD" ), &envStr );
// Add a new tab for system templates UpdateFileHistory( aProjectFileName.GetFullPath(), &PgmTop().GetFileHistory() );
if( !envStr.empty() )
{
// user may or may not have including terminating separator.
if( !envStr.EndsWith( sep ) )
envStr += sep;
templatePath = envStr + wxT( "template" ) + sep; m_LeftWin->ReCreateTreePrj();
}
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() ) ) // Rebuild the list of watched paths.
{ // however this is possible only when the main loop event handler is running,
templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) + // so we use it to run the rebuild function.
sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "template" ) + sep; wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
}
}
#else
// Use what is provided in the bundle data dir
templatePath = GetOSXKicadDataDir() + sep + wxT( "template" );
#endif
ps->AddTemplatesPage( _( "System Templates" ), templatePath ); wxPostEvent( this, cmd );
// Add a new tab for user templates PrintPrjInfo();
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 void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName )
// new selection tab if there is. {
envStr.clear(); wxCHECK_RET( aProjectFileName.DirExists() && aProjectFileName.IsDirWritable(),
wxGetEnv( wxT( "KICAD_PTEMPLATES" ), &envStr ); "Project folder must exist and be writable to create a new project." );
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 // Init project filename
SetProjectFileName( newProjectName.GetFullPath() ); SetProjectFileName( aProjectFileName.GetFullPath() );
// Write settings to project file
// was: wxGetApp().WriteProjectConfig( aPrjFullFileName, GeneralGroupName, s_KicadManagerParams );
Prj().ConfigSave( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
// Ensure a "stub" for a schematic root sheet and a board exist. // 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 // 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 // And forces the user to create main files under the right name for the project manager
wxFileName fn( newProjectName.GetFullPath() ); wxFileName fn( aProjectFileName.GetFullPath() );
fn.SetExt( SchematicFileExtension ); fn.SetExt( SchematicFileExtension );
// If a <project>.sch file does not exist, create a "stub" file // If a <project>.sch file does not exist, create a "stub" file ( minimal schematic file )
// ( minimal schematic file )
if( !fn.FileExists() ) if( !fn.FileExists() )
{ {
wxFile file( fn.GetFullPath(), wxFile::write ); wxFile file( fn.GetFullPath(), wxFile::write );
@ -197,169 +146,76 @@ void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName,
// wxFile dtor will close the file // 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::OnLoadProject( wxCommandEvent& event ) void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event )
{ {
// Any open KIFACE's must be closed if they are not part of the new project. wxString default_dir = GetMruPath();
// (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.) wxFileDialog dlg( this, _( "Open Existing Project" ), default_dir, wxEmptyString,
// User is prompted here to close those KIWAY_PLAYERs: ProjectFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( !Kiway.PlayersClose( false ) )
if( dlg.ShowModal() == wxID_CANCEL )
return; return;
// evt_id can be one of: wxFileName pro( dlg.GetPath() );
// ID_NEW_PROJECT, ID_NEW_PROJECT_FROM_TEMPLATE, ID_LOAD_PROJECT, and pro.SetExt( ProjectFileExtension ); // enforce extension
// wxID_ANY from 3 different places.
int evt_id = event.GetId();
wxString title; if( !pro.IsAbsolute() )
pro.MakeAbsolute();
ClearMsg(); if( !pro.FileExists() )
bool newProject = ( evt_id == ID_NEW_PROJECT ) ||
( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE );
if( evt_id != wxID_ANY )
{
int style;
if( newProject )
{
title = _( "Create New Project" );
style = wxFD_SAVE | wxFD_OVERWRITE_PROMPT;
}
else
{
title = _( "Open Existing Project" );
style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
}
wxString default_dir = GetMruPath();
wxFileDialog dlg( this, title, default_dir, wxEmptyString,
ProjectFileWildcard, style );
if( dlg.ShowModal() == wxID_CANCEL )
return;
//DBG( printf( "%s: wxFileDialog::GetPath=%s\n", __func__, TO_UTF8( dlg.GetPath() ) );)
wxFileName pro( dlg.GetPath() );
pro.SetExt( ProjectFileExtension ); // enforce extension
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
if( newProject )
{
// Check if the project directory is empty
wxDir directory( pro.GetPath() );
if( directory.HasFiles() )
{
wxString msg = _( "The selected directory is not empty. We recommend you "
"create projects in their own clean directory.\n\nDo you "
"want to create a new empty directory for the project?" );
if( IsOK( this, msg ) )
{
// Append a new directory with the same name of the project file
// and try to create it
pro.AppendDir( pro.GetName() );
if( !wxMkdir( pro.GetPath() ) )
// There was a problem, undo
pro.RemoveLastDir();
}
}
if( evt_id == ID_NEW_PROJECT )
{
CreateNewProject( pro.GetFullPath() );
}
else if( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE )
{
// Launch the template selector dialog
CreateNewProject( pro.GetFullPath(), true );
}
}
SetProjectFileName( pro.GetFullPath() );
}
wxString prj_filename = GetProjectFileName();
wxString nameless_prj = NAMELESS_PROJECT wxT( ".pro" );
wxLogDebug( wxT( "%s: %s" ),
GetChars( wxFileName( prj_filename ).GetFullName() ),
GetChars( nameless_prj ) );
// Check if project file exists and if it is not noname.pro
if( !wxFileExists( prj_filename )
&& !wxFileName( prj_filename ).GetFullName().IsSameAs( nameless_prj ) )
{
wxString msg = wxString::Format( _(
"KiCad project file '%s' not found" ),
GetChars( prj_filename ) );
DisplayError( this, msg );
return; return;
}
// Either this is the first time kicad has been run or one of the projects in the LoadProject( pro );
// history list is no longer valid. This prevents kicad from automatically creating }
// a noname.pro file in the same folder as the kicad binary.
if( wxFileName( prj_filename ).GetFullName().IsSameAs( nameless_prj ) && !newProject )
{ void KICAD_MANAGER_FRAME::OnNewProject( wxCommandEvent& aEvent )
m_active_project = false; {
m_MessagesBox->SetValue( _( "To proceed, you can use the File menu to start a new project." ) ); wxString default_dir = GetMruPath();
return; wxFileDialog dlg( this, _( "Create New Project" ), default_dir, wxEmptyString,
} ProjectFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
else
{ if( dlg.ShowModal() == wxID_CANCEL )
m_active_project = true; return;
m_MessagesBox->Clear();
} wxFileName pro( dlg.GetPath() );
pro.SetExt( ProjectFileExtension ); // enforce extension
Prj().ConfigLoad( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
if( !pro.IsAbsolute() )
title = L"KiCad \u2014 " + prj_filename; pro.MakeAbsolute();
if( !wxFileName( prj_filename ).IsDirWritable() ) // Check if the project directory is empty.
title += _( " [Read Only]" ); wxDir directory( pro.GetPath() );
else
SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. if( directory.HasFiles() )
{
SetTitle( title ); wxString msg = _( "The selected directory is not empty. We recommend you "
"create projects in their own clean directory.\n\nDo you "
if( !prj_filename.IsSameAs( nameless_prj ) ) "want to create a new empty directory for the project?" );
UpdateFileHistory( prj_filename, &PgmTop().GetFileHistory() );
if( IsOK( this, msg ) )
m_LeftWin->ReCreateTreePrj(); {
// Append a new directory with the same name of the project file
// Rebuild the list of watched paths. // and try to create it
// however this is possible only when the main loop event handler is running, pro.AppendDir( pro.GetName() );
// so we use it to run the rebuild function.
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS ); if( !wxMkdir( pro.GetPath() ) )
// There was a problem, undo
wxPostEvent( this, cmd ); pro.RemoveLastDir();
}
PrintPrjInfo(); }
CreateNewProject( pro.GetFullPath() );
LoadProject( pro );
} }
/* Creates a new project folder, copy a template into this new folder.
* and open this new project as working project
*/
void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event ) void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event )
{ {
wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep(); wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
wxString title = _("New Project Folder"); wxString title = _( "New Project Folder" );
wxDirDialog dlg( this, title, default_dir ); wxDirDialog dlg( this, title, default_dir );
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
@ -371,12 +227,158 @@ void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event )
fn.SetName( dlg.GetPath().AfterLast( SEP() ) ); fn.SetName( dlg.GetPath().AfterLast( SEP() ) );
fn.SetExt( wxT( "pro" ) ); fn.SetExt( wxT( "pro" ) );
// Launch the template selector dialog, and copy files wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string.
CreateNewProject( fn.GetFullPath(), true );
// Initialize the project ClearMsg();
event.SetId( wxID_ANY );
OnLoadProject( event ); 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
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;
}
// Make sure the user has write permissions to the base path.
wxFileName prjPath = fn;
while( !prjPath.DirExists() )
prjPath.RemoveLastDir();
if( !prjPath.IsDirWritable() )
{
wxString msg;
msg.Printf( _( "Cannot write to folder '%s'." ), prjPath.GetPath() );
wxMessageDialog msgDlg( this, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
msgDlg.SetExtendedMessage( _( "Plese check your access permissions to this folder "
"and try again." ) );
msgDlg.ShowModal();
return;
}
// 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( auto file : destFiles )
{
if( file.FileExists() )
overwrittenFiles.push_back( file );
}
if( !overwrittenFiles.empty() )
{
wxString extendedMsg = _( "Overwriting files:" ) + "\n";
for( auto file : overwrittenFiles )
{
extendedMsg += "\n" + file.GetFullName();
}
wxMessageDialog owDlg( this,
_( "Are you sure you want to overwrite files in "
"the destination folder?" ),
_( "Warning!" ),
wxYES_NO | wxICON_QUESTION | wxCENTER );
owDlg.SetExtendedMessage( extendedMsg );
owDlg.SetYesNoLabels( _( "Overwrite" ), _( "Do Not Overwrite" ) );
if( owDlg.ShowModal() == wxID_NO )
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 );
} }
@ -385,8 +387,6 @@ void KICAD_MANAGER_FRAME::OnSaveProject( wxCommandEvent& event )
if( !wxIsWritable( GetProjectFileName() ) ) if( !wxIsWritable( GetProjectFileName() ) )
return; return;
// was: wxGetApp().WriteProjectConfig( m_ProjectFileName.GetFullPath(),
// GeneralGroupName, s_KicadManagerParams );
Prj().ConfigSave( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams ); Prj().ConfigSave( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com> * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -27,6 +27,7 @@
#include <wx/dir.h> #include <wx/dir.h>
#include <wx/txtstrm.h> #include <wx/txtstrm.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <wx/log.h>
#include "project_template.h" #include "project_template.h"
@ -44,29 +45,29 @@ PROJECT_TEMPLATE::PROJECT_TEMPLATE( const wxString& aPath )
title = wxEmptyString; title = wxEmptyString;
// Test the project template requirements to make sure aPath is a valid // Test the project template requirements to make sure aPath is a valid template structure.
// template structure
if( !wxFileName::DirExists( templateBasePath.GetPath() ) ) if( !wxFileName::DirExists( templateBasePath.GetPath() ) )
{ {
// Error, the path doesn't exist! // Error, the path doesn't exist!
title = wxT( "Could open the template path! " + aPath ); title = _( "Could open the template path! " ) + aPath;
} }
else if( !wxFileName::DirExists( templateMetaPath.GetPath() ) ) else if( !wxFileName::DirExists( templateMetaPath.GetPath() ) )
{ {
// Error, the meta information directory doesn't exist! // Error, the meta information directory doesn't exist!
title = wxT( "Couldn't open the meta information directory for this template! " + title = _( "Couldn't open the meta information directory for this template! " ) +
templateMetaPath.GetPath() ); templateMetaPath.GetPath();
} }
else if( !wxFileName::FileExists( templateMetaHtmlFile.GetFullPath() ) ) else if( !wxFileName::FileExists( templateMetaHtmlFile.GetFullPath() ) )
{ {
// Error, the meta information directory doesn't contain the informational html file! // Error, the meta information directory doesn't contain the informational html file!
title = wxT( "Cound't find the meta html information file for this template!" ); title = _( "Cound't find the meta HTML information file for this template!" );
} }
// Try to load an icon // Try to load an icon
metaIcon = new wxBitmap( templateMetaIconFile.GetFullPath(), wxBITMAP_TYPE_PNG ); metaIcon = new wxBitmap( templateMetaIconFile.GetFullPath(), wxBITMAP_TYPE_PNG );
} }
std::vector<wxFileName> PROJECT_TEMPLATE::GetFileList() std::vector<wxFileName> PROJECT_TEMPLATE::GetFileList()
{ {
std::vector<wxFileName> files; std::vector<wxFileName> files;
@ -83,7 +84,7 @@ std::vector<wxFileName> PROJECT_TEMPLATE::GetFileList()
// Files that are in the meta directory must not be included // Files that are in the meta directory must not be included
if( !p.GetPath().StartsWith( templateMetaPath.GetPath() ) ) if( !p.GetPath().StartsWith( templateMetaPath.GetPath() ) )
files.push_back(allfiles[i]); files.push_back( allfiles[i] );
} }
return files; return files;
@ -114,7 +115,45 @@ wxBitmap* PROJECT_TEMPLATE::GetIcon()
} }
bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath ) size_t PROJECT_TEMPLATE::GetDestinationFiles( const wxFileName& aNewProjectPath,
std::vector< wxFileName >& aDestFiles )
{
std::vector< wxFileName > srcFiles = GetFileList();
// Find the template file name base. this is the name of the .pro template file
wxString basename;
for( auto file : srcFiles )
{
if( file.GetExt() == wxT( "pro" ) )
{
basename = file.GetName();
break;
}
}
for( auto file : srcFiles )
{
wxFileName destFile = file;
// Replace the template filename with the project filename for the new project creation
wxString name = destFile.GetName();
name.Replace( basename, aNewProjectPath.GetName() );
destFile.SetName( name );
// Replace the template path with the project path.
wxString path = destFile.GetPathWithSep();
path.Replace( templateBasePath.GetPathWithSep(), aNewProjectPath.GetPathWithSep() );
destFile.SetPath( path );
aDestFiles.push_back( destFile );
}
return aDestFiles.size();
}
bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath, wxString* aErrorMsg )
{ {
// CreateProject copy the files from template to the new project folder // CreateProject copy the files from template to the new project folder
// and rename files which have the same name as the template .pro file // and rename files which have the same name as the template .pro file
@ -122,8 +161,9 @@ bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath )
std::vector<wxFileName> srcFiles = GetFileList(); std::vector<wxFileName> srcFiles = GetFileList();
// Find the template file name base. this is the name of the .pro templte file // Find the template file name base. this is the name of the .pro template file
wxString basename; wxString basename;
for( size_t i=0; i < srcFiles.size(); i++ ) for( size_t i=0; i < srcFiles.size(); i++ )
{ {
if( srcFiles[i].GetExt() == wxT( "pro" ) ) if( srcFiles[i].GetExt() == wxT( "pro" ) )
@ -152,7 +192,23 @@ bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath )
// about error checking, if the path isn't created the file copy will fail anyway // about error checking, if the path isn't created the file copy will fail anyway
if( !wxFileName::DirExists( destpath ) ) if( !wxFileName::DirExists( destpath ) )
wxFileName::Mkdir( destpath, 0777, wxPATH_MKDIR_FULL ); {
if( !wxFileName::Mkdir( destpath, 0777, wxPATH_MKDIR_FULL ) )
{
if( aErrorMsg )
{
if( !aErrorMsg->empty() )
*aErrorMsg += "\n";
wxString msg;
msg.Printf( _( "Cannot create folder '%s'." ), destpath );
*aErrorMsg += msg;
}
continue;
}
}
destination.SetPath( destpath ); destination.SetPath( destpath );
@ -161,8 +217,19 @@ bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath )
if( !wxCopyFile( srcFile, dstFile ) ) if( !wxCopyFile( srcFile, dstFile ) )
{ {
if( aErrorMsg )
{
if( !aErrorMsg->empty() )
*aErrorMsg += "\n";
wxString msg;
msg.Printf( _( "Cannot copy file '%s'." ), dstFile );
*aErrorMsg += msg;
}
result = false; result = false;
break;
} }
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com> * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -112,38 +112,36 @@
class wxBitmap; class wxBitmap;
class wxFileName;
/** /**
* @brief A directory which contains information about the project template and does not get * A directory which contains information about the project template and does not get
* copied. This define is the default filename for this directory * copied. This define is the default filename for this directory
* *
*/ */
#define METADIR wxT("meta") #define METADIR wxT( "meta" )
/** /**
* @brief A required html formatted file which contains information about the project template. * A required html formatted file which contains information about the project template.
* This define is the default filename for this file * This define is the default filename for this file
* *
*/ */
#define METAFILE_INFO_HTML wxT("info.html") #define METAFILE_INFO_HTML wxT( "info.html" )
/** /**
* @brief An optional png icon, exactly 64px x 64px which is used in the template selector if * An optional png icon, exactly 64px x 64px which is used in the template selector if
* present. This define is the default filename for this file * present. This define is the default filename for this file
* *
*/ */
#define METAFILE_ICON wxT("icon.png") #define METAFILE_ICON wxT( "icon.png" )
/** /**
* @brief A class which provides project template functionality. * A class which provides project template functionality.
*
*
*
*/ */
class PROJECT_TEMPLATE { class PROJECT_TEMPLATE
private: {
protected: protected:
wxFileName templateBasePath; wxFileName templateBasePath;
wxFileName templateMetaPath; wxFileName templateMetaPath;
@ -155,7 +153,7 @@ protected:
public: public:
/** /**
* @brief Create a new project instance from \a aPath. \a aPath should be a directory that * Create a new project instance from \a aPath. \a aPath should be a directory that
* conforms to the project template requirements * conforms to the project template requirements
* *
* @param aPath Should be a directory containing the template * @param aPath Should be a directory containing the template
@ -163,45 +161,61 @@ public:
PROJECT_TEMPLATE( const wxString& aPath ); PROJECT_TEMPLATE( const wxString& aPath );
/** /**
* @brief Non-virtual destructor (so no dervied classes) * Non-virtual destructor (so no derived classes)
*/ */
~PROJECT_TEMPLATE(); ~PROJECT_TEMPLATE();
/** /**
* @brief Get the dir name of the project template * Get the dir name of the project template (i.e. the name of the last folder containing
* (i.e. the name of the last folder containing the template files) * the template files)
*
* @return the dir name of the template * @return the dir name of the template
*/ */
wxString GetPrjDirName(); wxString GetPrjDirName();
/** /**
* @brief Get the full Html filename for the project template * Get the full Html filename for the project template
*
* @return the html meta information file for this template * @return the html meta information file for this template
*/ */
wxFileName GetHtmlFile(); wxFileName GetHtmlFile();
/** /**
* @brief Copies and renames all template files to create a new project. * Copies and renames all template files to create a new project.
*
* @param aNewProjectPath The full path of the new project file to create * @param aNewProjectPath The full path of the new project file to create
* @param aErrorMsg is an optional string to place project creation error messages.
* @return true if the project creation was successful otherwise false.
*/ */
bool CreateProject( wxFileName& aNewProjectPath ); bool CreateProject( wxFileName& aNewProjectPath, wxString* aErrorMsg = nullptr );
/** /**
* @brief Get the 64px^2 icon for the project template * Get the 64px^2 icon for the project template
*
* @return an image file of 64px x 64px which is the templates icon * @return an image file of 64px x 64px which is the templates icon
*/ */
wxBitmap* GetIcon(); wxBitmap* GetIcon();
/** /**
* @brief Get the title of the project (extracted from the html title tag) * Get the title of the project (extracted from the html title tag)
*/ */
wxString* GetTitle(); wxString* GetTitle();
/** /**
* @brief Get a vector list of filenames for the template. The files are the source files, * Get a vector list of filenames for the template. The files are the source files,
* and have not yet been through any renaming * and have not yet been through any renaming
*/ */
std::vector<wxFileName> GetFileList(); std::vector<wxFileName> GetFileList();
/**
* Fetch the list of destination files to be copied when the new project is created.
*
* @param aNewProjectPath is the path to the project to be created.
* @param aDestFiles is a container to place the list of destination files to be created.
* @return the number of destination files added to the container.
*/
size_t GetDestinationFiles( const wxFileName& aNewProjectPath,
std::vector< wxFileName >& aDestFiles );
}; };
#endif #endif