const wxString WORKSHEET_LAYOUT::MakeFullFileName( const wxString& aShortFileName, const wxString& aProjectPath ) { wxString fullFileName = ExpandEnvVarSubstitutions( aShortFileName ); if( fullFileName.IsEmpty() ) return fullFileName; wxFileName fn = fullFileName; if( fn.IsAbsolute() ) return fullFileName; // the path is not absolute: search it in project path, and then in // kicad valid paths if( !aProjectPath.IsEmpty() ) { fn.MakeAbsolute( aProjectPath ); if( wxFileExists( fn.GetFullPath() ) ) return fn.GetFullPath(); } fn = fullFileName; wxString name = Kiface().KifaceSearch().FindValidPath( fn.GetFullName() ); if( !name.IsEmpty() ) fullFileName = name; return fullFileName; }
void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath, std::list< wxString >& aSearchList ) { // check the existence of a path and add it to the path search list if( aPath.empty() ) return; #ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] checking for 3D plugins in '%s'\n", aPath.ToUTF8() ); #endif wxFileName path; if( aPath.StartsWith( "${" ) || aPath.StartsWith( "$(" ) ) path.Assign( ExpandEnvVarSubstitutions( aPath ), "" ); else path.Assign( aPath, "" ); path.Normalize(); if( !wxFileName::DirExists( path.GetFullPath() ) ) return; // determine if the directory is already in the list wxString wxpath = path.GetFullPath(); std::list< wxString >::iterator bl = aSearchList.begin(); std::list< wxString >::iterator el = aSearchList.end(); while( bl != el ) { if( 0 == (*bl).Cmp( wxpath ) ) return; ++bl; } aSearchList.push_back( wxpath ); return; }
bool S3D_FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir ) { if( aConfigDir.empty() ) return false; wxFileName cfgdir; if( aConfigDir.StartsWith( "${" ) || aConfigDir.StartsWith( "$(" ) ) cfgdir.Assign( ExpandEnvVarSubstitutions( aConfigDir ), "" ); else cfgdir.Assign( aConfigDir, "" ); cfgdir.Normalize(); if( false == cfgdir.DirExists() ) return false; m_ConfigDir = cfgdir.GetPath(); createPathList(); return true; }
void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath, std::list< wxString >& aPluginList ) { // check the existence of a plugin name and add it to the list if( aPath.empty() || !wxFileName::FileExists( aPath ) ) return; wxFileName path; if( aPath.StartsWith( "${" ) || aPath.StartsWith( "$(" ) ) path.Assign( ExpandEnvVarSubstitutions( aPath ) ); else path.Assign( aPath ); path.Normalize(); // determine if the path is already in the list wxString wxpath = path.GetFullPath(); std::list< wxString >::iterator bl = aPluginList.begin(); std::list< wxString >::iterator el = aPluginList.end(); while( bl != el ) { if( 0 == (*bl).Cmp( wxpath ) ) return; ++bl; } aPluginList.push_back( wxpath ); #ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] found 3D plugin '%s'\n", wxpath.ToUTF8() ); #endif return; }
bool S3D_FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChanged ) { if( aProjDir.empty() ) return false; wxFileName projdir; if( aProjDir.StartsWith( "${" ) || aProjDir.StartsWith( "$(" ) ) projdir.Assign( ExpandEnvVarSubstitutions( aProjDir ), "" ); else projdir.Assign( aProjDir, "" ); projdir.Normalize(); if( false == projdir.DirExists() ) return false; m_curProjDir = projdir.GetPath(); if( flgChanged ) *flgChanged = false; if( m_Paths.empty() ) { S3D_ALIAS al; al.m_alias = "${KIPRJMOD}"; al.m_pathvar = "${KIPRJMOD}"; al.m_pathexp = m_curProjDir; m_Paths.push_back( al ); if( flgChanged ) *flgChanged = true; } else { if( m_Paths.front().m_pathexp.Cmp( m_curProjDir ) ) { m_Paths.front().m_pathexp = m_curProjDir; if( flgChanged ) *flgChanged = true; } else { return true; } } #ifdef DEBUG do { std::ostringstream ostr; ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; ostr << " * [INFO] changed project dir to "; ostr << m_Paths.front().m_pathexp.ToUTF8(); wxLogTrace( MASK_3D_RESOLVER, "%s\n", ostr.str().c_str() ); } while( 0 ); #endif return true; }
bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath ) { if( aPath.m_alias.empty() || aPath.m_pathvar.empty() ) return false; wxCriticalSectionLocker lock( lock3D_resolver ); S3D_ALIAS tpath = aPath; #ifdef _WIN32 while( tpath.m_pathvar.EndsWith( wxT( "\\" ) ) ) tpath.m_pathvar.erase( tpath.m_pathvar.length() - 1 ); #else while( tpath.m_pathvar.EndsWith( wxT( "/" ) ) && tpath.m_pathvar.length() > 1 ) tpath.m_pathvar.erase( tpath.m_pathvar.length() - 1 ); #endif wxFileName path; if( tpath.m_pathvar.StartsWith( "${" ) || tpath.m_pathvar.StartsWith( "$(" ) ) path.Assign( ExpandEnvVarSubstitutions( tpath.m_pathvar ), "" ); else path.Assign( tpath.m_pathvar, "" ); path.Normalize(); if( !path.DirExists() ) { // suppress the message if the missing pathvar is the // legacy KISYS3DMOD variable if( aPath.m_pathvar.compare( wxT( "${KISYS3DMOD}" ) ) ) { wxString msg = _( "The given path does not exist" ); msg.append( wxT( "\n" ) ); msg.append( tpath.m_pathvar ); wxMessageBox( msg, _( "3D model search path" ) ); } tpath.m_pathexp.clear(); } else { tpath.m_pathexp = path.GetFullPath(); #ifdef _WIN32 while( tpath.m_pathexp.EndsWith( wxT( "\\" ) ) ) tpath.m_pathexp.erase( tpath.m_pathexp.length() - 1 ); #else while( tpath.m_pathexp.EndsWith( wxT( "/" ) ) && tpath.m_pathexp.length() > 1 ) tpath.m_pathexp.erase( tpath.m_pathexp.length() - 1 ); #endif } wxString pname = path.GetPath(); std::list< S3D_ALIAS >::iterator sPL = m_Paths.begin(); std::list< S3D_ALIAS >::iterator ePL = m_Paths.end(); while( sPL != ePL ) { if( !tpath.m_alias.Cmp( sPL->m_alias ) ) { wxString msg = _( "Alias: " ); msg.append( tpath.m_alias ); msg.append( wxT( "\n" ) ); msg.append( _( "This path: " ) ); msg.append( tpath.m_pathvar ); msg.append( wxT( "\n" ) ); msg.append( _( "Existing path: " ) ); msg.append( sPL->m_pathvar ); wxMessageBox( msg, _( "Bad alias (duplicate name)" ) ); return false; } ++sPL; } m_Paths.push_back( tpath ); return true; }
wxString S3D_FILENAME_RESOLVER::ResolvePath( const wxString& aFileName ) { wxCriticalSectionLocker lock( lock3D_resolver ); if( aFileName.empty() ) return wxEmptyString; if( m_Paths.empty() ) createPathList(); // first attempt to use the name as specified: wxString tname = aFileName; #ifdef _WIN32 // translate from KiCad's internal UNIX-like path to MSWin paths tname.Replace( wxT( "/" ), wxT( "\\" ) ); #endif // Note: variable expansion must be performed using a threadsafe // wrapper for the getenv() system call. If we allow the // wxFileName::Normalize() routine to perform expansion then // we will have a race condition since wxWidgets does not assure // a threadsafe wrapper for getenv(). if( tname.StartsWith( "${" ) || tname.StartsWith( "$(" ) ) tname = ExpandEnvVarSubstitutions( tname ); wxFileName tmpFN( tname ); // in the case of absolute filenames we don't store a map item if( !aFileName.StartsWith( "${" ) && !aFileName.StartsWith( "$(" ) && !aFileName.StartsWith( ":" ) && tmpFN.IsAbsolute() ) { tmpFN.Normalize(); if( tmpFN.FileExists() ) return tmpFN.GetFullPath(); return wxEmptyString; } // this case covers full paths, leading expanded vars, and paths // relative to the current working directory (which is not necessarily // the current project directory) if( tmpFN.FileExists() ) { tmpFN.Normalize(); tname = tmpFN.GetFullPath(); // special case: if a path begins with ${ENV_VAR} but is not in the // resolver's path list then add it. if( aFileName.StartsWith( "${" ) || aFileName.StartsWith( "$(" ) ) checkEnvVarPath( aFileName ); return tname; } // if a path begins with ${ENV_VAR}/$(ENV_VAR) and is not resolved then the // file either does not exist or the ENV_VAR is not defined if( aFileName.StartsWith( "${" ) || aFileName.StartsWith( "$(" ) ) { if( !( m_errflags & ERRFLG_ENVPATH ) ) { m_errflags |= ERRFLG_ENVPATH; wxString errmsg = "[3D File Resolver] No such path; ensure the environment var is defined"; errmsg.append( "\n" ); errmsg.append( tname ); wxLogMessage( errmsg ); } return wxEmptyString; } // at this point aFileName is: // a. an aliased shortened name or // b. cannot be determined std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin(); std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end(); // check the path relative to the current project directory; // note: this is not necessarily the same as the current working // directory, which has already been checked. This case accounts // for partial paths which do not contain ${KIPRJMOD}. // This check is performed before checking the path relative to // ${KISYS3DMOD} so that users can potentially override a model // within ${KISYS3DMOD} if( !sPL->m_pathexp.empty() && !tname.StartsWith( ":" ) ) { tmpFN.Assign( sPL->m_pathexp, "" ); wxString fullPath = tmpFN.GetPathWithSep() + tname; if( fullPath.StartsWith( "${" ) || fullPath.StartsWith( "$(" ) ) fullPath = ExpandEnvVarSubstitutions( fullPath ); if( wxFileName::FileExists( fullPath ) ) { tmpFN.Assign( fullPath ); tmpFN.Normalize(); tname = tmpFN.GetFullPath(); return tname; } } // check the partial path relative to ${KISYS3DMOD} (legacy behavior) if( !tname.StartsWith( ":" ) ) { wxFileName fpath; wxString fullPath( "${KISYS3DMOD}" ); fullPath.Append( fpath.GetPathSeparator() ); fullPath.Append( tname ); fullPath = ExpandEnvVarSubstitutions( fullPath ); fpath.Assign( fullPath ); if( fpath.Normalize() && fpath.FileExists() ) { tname = fpath.GetFullPath(); return tname; } } // ${ENV_VAR} paths have already been checked; skip them while( sPL != ePL && ( sPL->m_alias.StartsWith( "${" ) || sPL->m_alias.StartsWith( "$(" ) ) ) ++sPL; // at this point the filename must contain an alias or else it is invalid wxString alias; // the alias portion of the short filename wxString relpath; // the path relative to the alias if( !SplitAlias( tname, alias, relpath ) ) { if( !( m_errflags & ERRFLG_RELPATH ) ) { // this can happen if the file was intended to be relative to // ${KISYS3DMOD} but ${KISYS3DMOD} not set or incorrect. m_errflags |= ERRFLG_RELPATH; wxString errmsg = "[3D File Resolver] No such path"; errmsg.append( "\n" ); errmsg.append( tname ); wxLogTrace( MASK_3D_RESOLVER, errmsg ); } return wxEmptyString; } while( sPL != ePL ) { if( !sPL->m_alias.Cmp( alias ) && !sPL->m_pathexp.empty() ) { wxFileName fpath( wxFileName::DirName( sPL->m_pathexp ) ); wxString fullPath = fpath.GetPathWithSep() + relpath; if( fullPath.StartsWith( "${") || fullPath.StartsWith( "$(" ) ) fullPath = ExpandEnvVarSubstitutions( fullPath ); if( wxFileName::FileExists( fullPath ) ) { wxFileName tmp( fullPath ); if( tmp.Normalize() ) tname = tmp.GetFullPath(); return tname; } } ++sPL; } if( !( m_errflags & ERRFLG_ALIAS ) ) { m_errflags |= ERRFLG_ALIAS; wxString errmsg = "[3D File Resolver] No such path; ensure the path alias is defined"; errmsg.append( "\n" ); errmsg.append( tname.substr( 1 ) ); wxLogTrace( MASK_3D_RESOLVER, errmsg ); } return wxEmptyString; }
bool S3D_FILENAME_RESOLVER::createPathList( void ) { if( !m_Paths.empty() ) return true; wxString kmod; // add an entry for the default search path; at this point // we cannot set a sensible default so we use an empty string. // the user may change this later with a call to SetProjectDir() S3D_ALIAS lpath; lpath.m_alias = "${KIPRJMOD}"; lpath.m_pathvar = "${KIPRJMOD}"; lpath.m_pathexp = m_curProjDir; m_Paths.push_back( lpath ); wxFileName fndummy; wxUniChar psep = fndummy.GetPathSeparator(); std::list< wxString > epaths; if( GetKicadPaths( epaths ) ) { for( auto i : epaths ) { wxString pathVal = ExpandEnvVarSubstitutions( i ); if( pathVal.empty() ) { lpath.m_pathexp.clear(); } else { fndummy.Assign( pathVal, "" ); fndummy.Normalize(); lpath.m_pathexp = fndummy.GetFullPath(); } lpath.m_alias = i; lpath.m_pathvar = i; if( !lpath.m_pathexp.empty() && psep == *lpath.m_pathexp.rbegin() ) lpath.m_pathexp.erase( --lpath.m_pathexp.end() ); m_Paths.push_back( lpath ); } } if( !m_ConfigDir.empty() ) readPathList(); if( m_Paths.empty() ) return false; #ifdef DEBUG wxLogTrace( MASK_3D_RESOLVER, " * [3D model] search paths:\n" ); std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin(); std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end(); while( sPL != ePL ) { wxLogTrace( MASK_3D_RESOLVER, " + %s : '%s'\n", (*sPL).m_alias.GetData(), (*sPL).m_pathexp.GetData() ); ++sPL; } #endif return true; }