31#include <wx/mimetype.h>
40#include "wx/tokenzr.h"
42#include <wx/wfstream.h>
44#include <wx/zipstrm.h>
50 if( !
string.StartsWith( wxT(
"\"" ) ) )
52 string.Prepend ( wxT(
"\"" ) );
53 string.Append ( wxT(
"\"" ) );
67 if( wxFileExists( fullFileName ) )
70 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
72 wxFileName buildDir(
Pgm().GetExecutablePath(), shortname );
73 buildDir.RemoveLastDir();
75 buildDir.AppendDir( shortname );
77 buildDir.AppendDir( shortname.BeforeLast(
'.' ) );
80 if( buildDir.GetDirs().Last() ==
"pl_editor" )
82 buildDir.RemoveLastDir();
83 buildDir.AppendDir(
"pagelayout_editor" );
86 if( wxFileExists( buildDir.GetFullPath() ) )
87 return buildDir.GetFullPath();
92 if(
Pgm().IsKicadEnvVariableDefined() )
96 if( wxFileExists( fullFileName ) )
100#if defined( __WINDOWS__ )
107 const static wxChar* possibilities[] = {
108#if defined( __WXMAC__ )
110 wxT(
"Contents/Applications/pcbnew.app/Contents/MacOS/" ),
111 wxT(
"Contents/Applications/eeschema.app/Contents/MacOS/" ),
112 wxT(
"Contents/Applications/gerbview.app/Contents/MacOS/" ),
113 wxT(
"Contents/Applications/bitmap2component.app/Contents/MacOS/" ),
114 wxT(
"Contents/Applications/pcb_calculator.app/Contents/MacOS/" ),
115 wxT(
"Contents/Applications/pl_editor.app/Contents/MacOS/" ),
118 wxT(
"/usr/local/bin/" ),
119 wxT(
"/usr/local/kicad/bin/" ),
124 for(
unsigned i=0; i<
arrayDim(possibilities); ++i )
127 fullFileName = possibilities[i] + shortname;
133 if( wxFileExists( fullFileName ) )
143int ExecuteFile(
const wxString& aEditorName,
const wxString& aFileName, wxProcess* aCallback,
146 wxString fullEditorName;
147 std::vector<wxString> params;
151 bool inSingleQuotes =
false;
152 bool inDoubleQuotes =
false;
157 if( !param.IsEmpty() )
159 params.push_back( param );
164 for( wxUniChar ch : aEditorName )
171 inSingleQuotes =
false;
179 else if( inDoubleQuotes )
184 inDoubleQuotes =
false;
191 else if( ch ==
'\'' )
194 inSingleQuotes =
true;
199 inDoubleQuotes =
true;
216 fullEditorName = params[0];
218 params.erase( params.begin() );
224 fullEditorName = aEditorName;
227 if( wxFileExists( fullEditorName ) )
229 std::vector<const wchar_t*> args;
231 args.emplace_back( fullEditorName.wc_str() );
233 if( !params.empty() )
235 for(
const wxString& p : params )
236 args.emplace_back( p.wc_str() );
239 if( !aFileName.IsEmpty() )
240 args.emplace_back( aFileName.wc_str() );
242 args.emplace_back(
nullptr );
244 return wxExecute(
const_cast<wchar_t**
>( args.data() ), wxEXEC_ASYNC, aCallback );
248 msg.Printf(
_(
"Command '%s' could not be found." ), fullEditorName );
257 wxString filename = file;
261 if(
Pgm().UseSystemPdfBrowser() )
265 msg.Printf(
_(
"Unable to find a PDF viewer for '%s'." ), filename );
272 const wchar_t* args[3];
275 args[1] = filename.wc_str();
278 if( wxExecute(
const_cast<wchar_t**
>( args ) ) == -1 )
280 msg.Printf(
_(
"Problem while running the PDF viewer '%s'." ), args[0] );
290void KiCopyFile(
const wxString& aSrcPath,
const wxString& aDestPath, wxString& aErrors )
292 if( !wxCopyFile( aSrcPath, aDestPath ) )
296 if( !aErrors.IsEmpty() )
299 msg.Printf(
_(
"Cannot copy file '%s'." ), aDestPath );
307 return wxT(
"\"" ) + fn.GetFullPath( format ) + wxT(
"\"" );
313 namespace fs = std::filesystem;
315 std::string rmDir = aFileName.ToStdString();
317 if( rmDir.length() < 3 )
320 *aErrors =
_(
"Invalid directory name, cannot remove root" );
325 if( !fs::exists( rmDir ) )
328 *aErrors = wxString::Format(
_(
"Directory '%s' does not exist" ), aFileName );
333 fs::path
path( rmDir );
335 if( !fs::is_directory(
path ) )
338 *aErrors = wxString::Format(
_(
"'%s' is not a directory" ), aFileName );
345 fs::remove_all(
path );
347 catch(
const fs::filesystem_error& e )
350 *aErrors = wxString::Format(
_(
"Error removing directory '%s': %s" ),
351 aFileName, e.what() );
360bool CopyDirectory(
const wxString& aSourceDir,
const wxString& aDestDir, wxString& aErrors )
362 wxDir dir( aSourceDir );
364 if( !dir.IsOpened() )
366 aErrors += wxString::Format(
_(
"Could not open source directory: %s" ), aSourceDir );
367 aErrors += wxT(
"\n" );
371 if( !wxFileName::Mkdir( aDestDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
373 aErrors += wxString::Format(
_(
"Could not create destination directory: %s" ), aDestDir );
374 aErrors += wxT(
"\n" );
379 bool cont = dir.GetFirst( &filename );
383 wxString sourcePath = aSourceDir + wxFileName::GetPathSeparator() + filename;
384 wxString destPath = aDestDir + wxFileName::GetPathSeparator() + filename;
386 if( wxFileName::DirExists( sourcePath ) )
395 if( !wxCopyFile( sourcePath, destPath ) )
397 aErrors += wxString::Format(
_(
"Could not copy file: %s to %s" ),
404 cont = dir.GetNext( &filename );
412 int& fileCopiedCount,
const std::vector<wxString>& aExclusions )
414 wxFileName sourceFn( aSourcePath );
415 wxDir dir( sourceFn.GetPath() );
416 wxFileName destFn( aDestDir );
418 if( !dir.IsOpened() )
420 aErrors += wxString::Format(
_(
"Could not open source directory: %s" ),
421 sourceFn.GetPath() );
422 aErrors += wxT(
"\n" );
426 if( !wxFileName::Mkdir( aDestDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
428 aErrors += wxString::Format(
_(
"Could not create destination directory: %s" ),
430 aErrors += wxT(
"\n" );
434 wxString filename = sourceFn.GetFullName();
435 bool cont = dir.GetFirst( &filename, sourceFn.GetFullName(), wxDIR_FILES | wxDIR_DIRS );
439 wxString sourcePath = sourceFn.GetPath() + wxFileName::GetPathSeparator() + filename;
440 wxString destPath = aDestDir + wxFileName::GetPathSeparator() + filename;
441 bool exclude = filename.Matches( wxT(
"~*.lck" ) );
443 for(
const wxString& exclusion : aExclusions )
444 exclude |= sourcePath.Matches( exclusion );
448 cont = dir.GetNext( &filename );
453 if( sourcePath == aSourcePath )
456 if( wxFileName::DirExists( sourcePath ) )
468 if( !wxCopyFile( sourcePath, destPath ) )
470 aErrors += wxString::Format(
_(
"Could not copy file: %s to %s" ), sourcePath,
477 cont = dir.GetNext( &filename );
485 const wxString& aParentDir )
487 wxDir dir( aSourceDir );
489 if( !dir.IsOpened() )
491 aErrors += wxString::Format(
_(
"Could not open source directory: %s" ), aSourceDir );
497 bool cont = dir.GetFirst( &filename );
501 wxString sourcePath = aSourceDir + wxFileName::GetPathSeparator() + filename;
502 wxString zipPath = aParentDir + filename;
504 if( wxFileName::DirExists( sourcePath ) )
507 aZip.PutNextDirEntry( zipPath +
"/" );
516 aZip.PutNextEntry( zipPath );
517 wxFFileInputStream fileStream( sourcePath );
519 if( !fileStream.IsOk() )
521 aErrors += wxString::Format(
_(
"Could not read file: %s" ), sourcePath );
525 aZip.Write( fileStream );
528 cont = dir.GetNext( &filename );
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
virtual const wxString & GetKicadEnvVariable() const
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
virtual const wxString & GetPdfBrowserName() const
virtual const wxString & GetExecutablePath() const
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
wxString FindKicadFile(const wxString &shortname)
Search the executable file shortname in KiCad binary path and return full file name if found or short...
wxString QuoteFullPath(wxFileName &fn, wxPathFormat format)
Quote return value of wxFileName::GetFullPath().
bool OpenPDF(const wxString &file)
Run the PDF viewer and display a PDF file.
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
bool CopyFilesOrDirectory(const wxString &aSourcePath, const wxString &aDestDir, wxString &aErrors, int &fileCopiedCount, const std::vector< wxString > &aExclusions)
bool RmDirRecursive(const wxString &aFileName, wxString *aErrors)
Remove the directory aDirName and all its contents including subdirectories and their files.
void QuoteString(wxString &string)
Add un " to the start and the end of string (if not already done).
bool CopyDirectory(const wxString &aSourceDir, const wxString &aDestDir, wxString &aErrors)
Copy a directory and its contents to another directory.
bool AddDirectoryToZip(wxZipOutputStream &aZip, const wxString &aSourceDir, wxString &aErrors, const wxString &aParentDir)
Add a directory and its contents to a zip file.
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
PGM_BASE & Pgm()
The global program "get" accessor.