Work in progress: transition to new 3D name resolution with nicknames
This commit is contained in:
parent
d519df22ca
commit
2ed89c29d2
|
@ -51,16 +51,6 @@
|
|||
|
||||
#define CACHE_CONFIG_NAME wxT( "cache.cfg" )
|
||||
|
||||
void display(unsigned char* hash)
|
||||
{
|
||||
std::cout << "SHA1: " << std::hex;
|
||||
for(int i = 0; i < 20; ++i)
|
||||
{
|
||||
std::cout << ((hash[i] & 0x000000F0) >> 4)
|
||||
<< (hash[i] & 0x0000000F);
|
||||
}
|
||||
std::cout << std::endl; // Das wars
|
||||
}
|
||||
|
||||
static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
|
||||
{
|
||||
|
@ -91,7 +81,6 @@ static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
|
|||
}
|
||||
|
||||
sha1[j] = 0;
|
||||
std::cerr << "XXX: SHA1: " << sha1 << "\n";
|
||||
|
||||
return wxString::FromUTF8Unchecked( sha1 );
|
||||
}
|
||||
|
@ -265,7 +254,7 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
|
|||
|
||||
if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
|
||||
{
|
||||
// just in case we can't get an MD5 sum (for example, on access issues)
|
||||
// just in case we can't get an hash digest (for example, on access issues)
|
||||
// or we do not have a configured cache file directory, we create an
|
||||
// entry to prevent further attempts at loading the file
|
||||
S3D_CACHE_ENTRY* ep = new S3D_CACHE_ENTRY;
|
||||
|
@ -381,8 +370,6 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
|
|||
aSHA1Sum[idx] = tmp & 0xff;
|
||||
}
|
||||
|
||||
display( aSHA1Sum );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -712,3 +699,28 @@ S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
|
|||
|
||||
return mp;
|
||||
}
|
||||
|
||||
|
||||
wxString S3D_CACHE::GetModelHash( const wxString& aModelFileName )
|
||||
{
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFileName );
|
||||
|
||||
if( full3Dpath.empty() || !wxFileName::FileExists( full3Dpath ) )
|
||||
return wxEmptyString;
|
||||
|
||||
// check cache if file is already loaded
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString >::iterator mi;
|
||||
mi = m_CacheMap.find( full3Dpath );
|
||||
|
||||
if( mi != m_CacheMap.end() )
|
||||
return mi->second->GetCacheBaseName();
|
||||
|
||||
// a cache item does not exist; search the Filename->Cachename map
|
||||
S3D_CACHE_ENTRY* cp = NULL;
|
||||
checkCache( full3Dpath, &cp );
|
||||
|
||||
if( NULL != cp )
|
||||
return cp->GetCacheBaseName();
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
|
|
@ -191,6 +191,8 @@ public:
|
|||
* @return is a pointer to the render data or NULL if not available
|
||||
*/
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName );
|
||||
|
||||
wxString GetModelHash( const wxString& aModelFileName );
|
||||
};
|
||||
|
||||
#endif // CACHE_3D_H
|
||||
|
|
|
@ -25,13 +25,28 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/utils.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include "3d_filename_resolver.h"
|
||||
|
||||
#define S3D_RESOLVER_CONFIG wxT( "3Dresolver.cfg" )
|
||||
|
||||
// flag bits used to track different one-off messages to users
|
||||
#define ERRFLG_NODIR (1)
|
||||
#define ERRFLG_RELPATH (2)
|
||||
|
||||
|
||||
static bool getHollerith( const std::string& aString, size_t& aIndex, wxString& aResult );
|
||||
|
||||
|
||||
S3D_FILENAME_RESOLVER::S3D_FILENAME_RESOLVER()
|
||||
{
|
||||
m_errflags = 0;
|
||||
}
|
||||
|
||||
|
||||
bool S3D_FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
{
|
||||
|
@ -69,7 +84,13 @@ bool S3D_FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgCh
|
|||
|
||||
if( m_Paths.empty() )
|
||||
{
|
||||
m_Paths.push_back( path );
|
||||
S3D_ALIAS al;
|
||||
al.m_alias = _( "(DEFAULT)" );
|
||||
al.m_pathvar = _( "${PROJDIR}" );
|
||||
al.m_pathexp = path;
|
||||
al.m_description = _( "Current project directory" );
|
||||
m_Paths.push_back( al );
|
||||
m_NameMap.clear();
|
||||
|
||||
if( flgChanged )
|
||||
*flgChanged = true;
|
||||
|
@ -77,10 +98,9 @@ bool S3D_FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgCh
|
|||
}
|
||||
else
|
||||
{
|
||||
if( m_Paths.front().Cmp( path ) )
|
||||
if( m_Paths.front().m_pathexp.Cmp( path ) )
|
||||
{
|
||||
m_Paths.pop_front();
|
||||
m_Paths.push_front( path );
|
||||
m_Paths.front().m_pathexp = path;
|
||||
m_NameMap.clear();
|
||||
|
||||
if( flgChanged )
|
||||
|
@ -95,7 +115,8 @@ bool S3D_FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgCh
|
|||
|
||||
#ifdef DEBUG
|
||||
std::cout << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cout << " * [INFO] changed project dir to " << m_Paths.front().ToUTF8() << "\n";
|
||||
std::cout << " * [INFO] changed project dir to ";
|
||||
std::cout << m_Paths.front().m_pathexp.ToUTF8() << "\n";
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -107,7 +128,7 @@ wxString S3D_FILENAME_RESOLVER::GetProjectDir( void )
|
|||
if( m_Paths.empty() )
|
||||
return wxEmptyString;
|
||||
|
||||
return m_Paths.front();
|
||||
return m_Paths.front().m_pathexp;
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,11 +143,27 @@ bool S3D_FILENAME_RESOLVER::createPathList( void )
|
|||
// default; since CWD is not necessarily what we really want,
|
||||
// the user may change this later with a call to SetProjectDir()
|
||||
|
||||
if( !addPath( wxFileName::GetCwd() ) )
|
||||
m_Paths.push_back( wxEmptyString );
|
||||
S3D_ALIAS lpath;
|
||||
lpath.m_alias = _( "(DEFAULT)" );
|
||||
lpath.m_pathvar = _( "(PROJECT DIR)" );
|
||||
lpath.m_pathexp = wxFileName::GetCwd();
|
||||
lpath.m_description = _( "Current project directory" );
|
||||
m_Paths.push_back( lpath );
|
||||
|
||||
if( wxGetEnv( wxT( "KISYS3DMOD" ), &kmod ) )
|
||||
addPath( kmod );
|
||||
if( wxGetEnv( wxT( "KISYS3DMOD" ), &kmod ) && !kmod.empty() )
|
||||
{
|
||||
wxFileName tmp( kmod );
|
||||
wxString kpath = tmp.GetFullPath();
|
||||
|
||||
if( tmp.Normalize() && lpath.m_pathexp.Cmp( kpath ) )
|
||||
{
|
||||
lpath.m_alias = wxT( "KISYS3DMOD" );
|
||||
lpath.m_pathvar = wxT( "${KISYS3DMOD}" );
|
||||
lpath.m_pathexp = kpath;
|
||||
lpath.m_description = _( "Legacy 3D environment path" );
|
||||
addPath( lpath );
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_ConfigDir.empty() )
|
||||
readPathList();
|
||||
|
@ -136,12 +173,12 @@ bool S3D_FILENAME_RESOLVER::createPathList( void )
|
|||
|
||||
#ifdef DEBUG
|
||||
std::cout << " * [3D model] search paths:\n";
|
||||
std::list< wxString >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< wxString >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
std::cout << " + '" << (*sPL).ToUTF8() << "'\n";
|
||||
std::cout << " + '" << (*sPL).m_pathexp.ToUTF8() << "'\n";
|
||||
++sPL;
|
||||
}
|
||||
#endif
|
||||
|
@ -150,7 +187,7 @@ bool S3D_FILENAME_RESOLVER::createPathList( void )
|
|||
}
|
||||
|
||||
|
||||
bool S3D_FILENAME_RESOLVER::UpdatePathList( std::vector< wxString >& aPathList )
|
||||
bool S3D_FILENAME_RESOLVER::UpdatePathList( std::vector< S3D_ALIAS >& aPathList )
|
||||
{
|
||||
while( m_Paths.size() > 1 )
|
||||
m_Paths.pop_back();
|
||||
|
@ -172,61 +209,125 @@ wxString S3D_FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
|||
if( m_Paths.empty() )
|
||||
createPathList();
|
||||
|
||||
// first attempt to use the name as specified:
|
||||
wxString aResolvedName;
|
||||
wxString fname;
|
||||
// look up the filename in the internal filename map
|
||||
std::map< wxString, wxString, S3D::rsort_wxString >::iterator mi;
|
||||
mi = m_NameMap.find( aFileName );
|
||||
|
||||
if( mi != m_NameMap.end() )
|
||||
return mi->second;
|
||||
|
||||
// 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
|
||||
|
||||
if( wxFileName::FileExists( tname ) )
|
||||
{
|
||||
wxFileName tmp( tname );
|
||||
|
||||
if( tmp.Normalize() )
|
||||
tname = tmp.GetFullPath();
|
||||
|
||||
m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
|
||||
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
return tname;
|
||||
}
|
||||
|
||||
// at this point aFileName:
|
||||
// a. is a legacy ${} shortened name
|
||||
// b. an aliased shortened name
|
||||
// c. cannot be determined
|
||||
|
||||
// normalize paths with "${VARNAME}" to support legacy behavior
|
||||
if( aFileName.StartsWith( wxT( "${" ) ) )
|
||||
{
|
||||
wxFileName tmp( aFileName );
|
||||
|
||||
if( tmp.Normalize() )
|
||||
fname = tmp.GetFullPath();
|
||||
else
|
||||
fname = aFileName;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = aFileName;
|
||||
tname = tmp.GetFullPath();
|
||||
m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
|
||||
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
return tname;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// translate from KiCad's internal UNIX-like path to MSWin paths
|
||||
fname.Replace( wxT( "/" ), wxT( "\\" ) );
|
||||
#endif
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
if( checkRealPath( fname, aResolvedName ) )
|
||||
return aResolvedName;
|
||||
// XXX - no such path - consider showing the user a pop-up message
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
// look up the filename in the internal filename map
|
||||
std::map< wxString, wxString, S3D::rsort_wxString >::iterator mi;
|
||||
mi = m_NameMap.find( fname );
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
if( mi != m_NameMap.end() )
|
||||
return mi->second;
|
||||
// check the path relative to the current dir
|
||||
do
|
||||
{
|
||||
wxFileName fpath( wxFileName::DirName( sPL->m_pathexp ) );
|
||||
wxString fullPath = fpath.GetPathWithSep() + tname;
|
||||
|
||||
std::list< wxString >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< wxString >::const_iterator ePL = m_Paths.end();
|
||||
if( wxFileName::FileExists( fullPath ) )
|
||||
{
|
||||
wxFileName tmp( fullPath );
|
||||
|
||||
if( tmp.Normalize() )
|
||||
tname = tmp.GetFullPath();
|
||||
|
||||
m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
|
||||
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
return tname;
|
||||
}
|
||||
} while( 0 );
|
||||
|
||||
++sPL;
|
||||
|
||||
wxString alias; // the alias portion of the short filename
|
||||
wxString relpath; // the path relative to the alias
|
||||
|
||||
if( !SplitAlias( aFileName, alias, relpath ) )
|
||||
{
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
// XXX - no such path - consider showing the user a pop-up message
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
wxFileName fpath( wxFileName::DirName( *sPL ) );
|
||||
wxFileName filename( fname );
|
||||
|
||||
// we can only attempt a search if the filename is incomplete
|
||||
if( filename.IsRelative() )
|
||||
if( !sPL->m_alias.Cmp( alias ) )
|
||||
{
|
||||
wxString fullPath = fpath.GetPathWithSep() + fname;
|
||||
wxFileName fpath( wxFileName::DirName( sPL->m_pathexp ) );
|
||||
wxString fullPath = fpath.GetPathWithSep() + relpath;
|
||||
|
||||
if( checkRealPath( fullPath, aResolvedName ) )
|
||||
return aResolvedName;
|
||||
if( wxFileName::FileExists( fullPath ) )
|
||||
{
|
||||
wxFileName tmp( fullPath );
|
||||
|
||||
if( tmp.Normalize() )
|
||||
tname = tmp.GetFullPath();
|
||||
|
||||
m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
|
||||
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
return tname;
|
||||
}
|
||||
}
|
||||
|
||||
++sPL;
|
||||
}
|
||||
|
||||
std::cerr << "XXX: RESOLVER LINE " << __LINE__ << "\n";
|
||||
|
||||
// XXX - no such path - consider showing the user a pop-up message
|
||||
wxString errmsg = _( "filename could not be resolved" );
|
||||
std::cerr << " * [3D Model] " << errmsg.ToUTF8() << " '";
|
||||
std::cerr << aFileName.ToUTF8() << "'\n";
|
||||
|
@ -235,52 +336,113 @@ wxString S3D_FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
|||
}
|
||||
|
||||
|
||||
bool S3D_FILENAME_RESOLVER::checkRealPath( const wxString& aFileName,
|
||||
wxString& aResolvedName )
|
||||
bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
|
||||
{
|
||||
aResolvedName.clear();
|
||||
wxFileName fname( aFileName );
|
||||
fname.Normalize();
|
||||
|
||||
if( !fname.FileExists() )
|
||||
if( aPath.m_alias.empty() || aPath.m_pathvar.empty() )
|
||||
return false;
|
||||
|
||||
aResolvedName = fname.GetFullPath();
|
||||
m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, aResolvedName ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool S3D_FILENAME_RESOLVER::addPath( const wxString& aPath )
|
||||
{
|
||||
if( aPath.empty() )
|
||||
return false;
|
||||
|
||||
wxFileName path( aPath, wxT( "" ) );
|
||||
wxFileName path( aPath.m_pathvar, wxT( "" ) );
|
||||
path.Normalize();
|
||||
|
||||
if( !path.DirExists() )
|
||||
{
|
||||
wxString errmsg = _( "invalid path" );
|
||||
std::cerr << " * [3D Model] " << errmsg.ToUTF8() << " '" << path.GetPath().ToUTF8() << "'\n";
|
||||
S3D_ALIAS tpath = aPath;
|
||||
|
||||
return false;
|
||||
}
|
||||
if( !path.DirExists() )
|
||||
tpath.m_pathexp.clear();
|
||||
else
|
||||
tpath.m_pathexp = path.GetFullPath();
|
||||
|
||||
wxString pname = path.GetPath();
|
||||
std::list< wxString >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< wxString >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
if( !pname.Cmp( *sPL ) )
|
||||
return true;
|
||||
if( !sPL->m_pathvar.empty() && !tpath.m_pathvar.empty()
|
||||
&& !tpath.m_pathvar.Cmp( sPL->m_pathvar ) )
|
||||
{
|
||||
wxString msg = _T( "This alias: " );
|
||||
msg.append( tpath.m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "This path: " ) );
|
||||
msg.append( tpath.m_pathvar );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing alias: " ) );
|
||||
msg.append( sPL->m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing path: " ) );
|
||||
msg.append( sPL->m_pathvar );
|
||||
wxMessageBox( msg, _T( "Bad alias (duplicate path)" ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !sPL->m_pathexp.empty() && !tpath.m_pathexp.empty() )
|
||||
{
|
||||
if( !tpath.m_pathexp.Cmp( sPL->m_pathexp ) )
|
||||
{
|
||||
wxString msg = _T( "This alias: " );
|
||||
msg.append( tpath.m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing alias: " ) );
|
||||
msg.append( sPL->m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "This path: " ) );
|
||||
msg.append( tpath.m_pathexp );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing path: " ) );
|
||||
msg.append( sPL->m_pathexp );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "This full path: " ) );
|
||||
msg.append( tpath.m_pathexp );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing full path: " ) );
|
||||
msg.append( sPL->m_pathexp );
|
||||
wxMessageBox( msg, _T( "Bad alias (duplicate path)" ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( tpath.m_pathexp.find( sPL->m_pathexp ) != wxString::npos
|
||||
|| sPL->m_pathexp.find( tpath.m_pathexp ) != wxString::npos )
|
||||
{
|
||||
wxString msg = _T( "This alias: " );
|
||||
msg.append( tpath.m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "This path: " ) );
|
||||
msg.append( tpath.m_pathexp );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing alias: " ) );
|
||||
msg.append( sPL->m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing path: " ) );
|
||||
msg.append( sPL->m_pathexp );
|
||||
wxMessageBox( msg, _T( "Bad alias (common path)" ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( !tpath.m_alias.Cmp( sPL->m_alias ) )
|
||||
{
|
||||
wxString msg = _T( "Alias: " );
|
||||
msg.append( tpath.m_alias );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "This path: " ) );
|
||||
msg.append( tpath.m_pathvar );
|
||||
msg.append( wxT( "\n" ) );
|
||||
msg.append( _T( "Existing path: " ) );
|
||||
msg.append( sPL->m_pathvar );
|
||||
wxMessageBox( msg, _T( "Bad alias (duplicate name)" ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
++sPL;
|
||||
}
|
||||
|
||||
m_Paths.push_back( pname );
|
||||
// Note: at this point we may still have duplicated paths
|
||||
|
||||
m_Paths.push_back( tpath );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -324,7 +486,8 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
|
|||
}
|
||||
|
||||
int lineno = 0;
|
||||
bool mod = false; // set to true if there are non-existent paths in the file
|
||||
S3D_ALIAS al;
|
||||
size_t idx;
|
||||
|
||||
while( cfgFile.good() )
|
||||
{
|
||||
|
@ -340,42 +503,22 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string::size_type spos = cfgLine.find_first_of( '"', 0 );
|
||||
idx = 0;
|
||||
|
||||
if( std::string::npos == spos )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "missing opening quote mark in config file" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << " '" << cfgname.ToUTF8() << "'\n";
|
||||
}
|
||||
if( !getHollerith( cfgLine, idx, al.m_alias ) )
|
||||
continue;
|
||||
|
||||
cfgLine.erase( 0, spos + 1 );
|
||||
if( !getHollerith( cfgLine, idx, al.m_pathvar ) )
|
||||
continue;
|
||||
|
||||
spos = cfgLine.find_last_of( '"' );
|
||||
if( !getHollerith( cfgLine, idx, al.m_description ) )
|
||||
continue;
|
||||
|
||||
if( std::string::npos == spos )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "missing closing quote mark in config file" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << " '" << cfgname.ToUTF8() << "'\n";
|
||||
}
|
||||
|
||||
cfgLine.erase( spos );
|
||||
|
||||
if( !addPath( cfgLine ) )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "invalid path in config file" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << " '" << cfgname.ToUTF8() << "'\n";
|
||||
mod = true;
|
||||
}
|
||||
addPath( al );
|
||||
}
|
||||
|
||||
cfgFile.close();
|
||||
|
||||
if( mod )
|
||||
writePathList();
|
||||
|
||||
if( m_Paths.size() != nitems )
|
||||
return true;
|
||||
|
||||
|
@ -410,16 +553,22 @@ bool S3D_FILENAME_RESOLVER::writePathList( void )
|
|||
return false;
|
||||
}
|
||||
|
||||
std::list< wxString >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< wxString >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
// the first entry is the current project dir; we never add a project dir
|
||||
// to the path list in the configuration file
|
||||
// the first entry is the current project dir; we never add the implicit
|
||||
// project dir to the path list in the configuration file
|
||||
++sPL;
|
||||
std::string tstr;
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
cfgFile << "\"" << sPL->ToUTF8() << "\"\n";
|
||||
tstr = sPL->m_alias.ToUTF8();
|
||||
cfgFile << "\"" << tstr.size() << ":" << tstr << "\",";
|
||||
tstr = sPL->m_pathvar.ToUTF8();
|
||||
cfgFile << "\"" << tstr.size() << ":" << tstr << "\",";
|
||||
tstr = sPL->m_description.ToUTF8();
|
||||
cfgFile << "\"" << tstr.size() << ":" << tstr << "\"\n";
|
||||
++sPL;
|
||||
}
|
||||
|
||||
|
@ -440,23 +589,56 @@ wxString S3D_FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
|||
if( m_Paths.empty() )
|
||||
createPathList();
|
||||
|
||||
std::list< wxString >::const_iterator sL = m_Paths.begin();
|
||||
std::list< wxString >::const_iterator eL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator eL = m_Paths.end();
|
||||
size_t idx;
|
||||
|
||||
// test for files within the current project directory
|
||||
if( !sL->m_pathexp.empty() )
|
||||
{
|
||||
wxFileName fpath( sL->m_pathexp, wxT( "" ) );
|
||||
wxString fps = fpath.GetPathWithSep();
|
||||
|
||||
idx = fname.find( fps );
|
||||
|
||||
if( std::string::npos != idx && 0 == idx )
|
||||
{
|
||||
fname = fname.substr( fps.size() );
|
||||
return fname;
|
||||
}
|
||||
}
|
||||
|
||||
++sL;
|
||||
|
||||
while( sL != eL )
|
||||
{
|
||||
wxFileName fpath( *sL, wxT( "" ) );
|
||||
wxString fps = fpath.GetPathWithSep();
|
||||
if( sL->m_pathexp.empty() )
|
||||
{
|
||||
++sL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( std::string::npos != fname.find( fps ) )
|
||||
wxFileName fpath( sL->m_pathexp, wxT( "" ) );
|
||||
wxString fps = fpath.GetPathWithSep();
|
||||
wxString tname;
|
||||
|
||||
idx = fname.find( fps );
|
||||
|
||||
if( std::string::npos != idx && 0 == idx )
|
||||
{
|
||||
fname = fname.substr( fps.size() );
|
||||
|
||||
#ifdef _WIN32
|
||||
// ensure only the '/' separator is used in the internal name
|
||||
fname.Replace( wxT( "\\" ), wxT( "/" ) );
|
||||
#endif
|
||||
|
||||
return fname;
|
||||
tname = ":";
|
||||
tname.append( sL->m_alias );
|
||||
tname.append( ":" );
|
||||
tname.append( fname );
|
||||
|
||||
return tname;
|
||||
}
|
||||
|
||||
++sL;
|
||||
|
@ -475,7 +657,114 @@ wxString S3D_FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
|||
|
||||
|
||||
|
||||
const std::list< wxString >* S3D_FILENAME_RESOLVER::GetPaths( void )
|
||||
const std::list< S3D_ALIAS >* S3D_FILENAME_RESOLVER::GetPaths( void )
|
||||
{
|
||||
return &m_Paths;
|
||||
}
|
||||
|
||||
|
||||
bool S3D_FILENAME_RESOLVER::SplitAlias( const wxString& aFileName,
|
||||
wxString& anAlias, wxString& aRelPath )
|
||||
{
|
||||
anAlias.clear();
|
||||
aRelPath.clear();
|
||||
|
||||
if( !aFileName.StartsWith( wxT( ":" ) ) )
|
||||
return false;
|
||||
|
||||
size_t tagpos = aFileName.find( wxT( ":" ), 1 );
|
||||
|
||||
if( wxString::npos == tagpos || 1 == tagpos )
|
||||
return false;
|
||||
|
||||
if( tagpos + 1 >= aFileName.length() )
|
||||
return false;
|
||||
|
||||
anAlias = aFileName.substr( 1, tagpos - 1 );
|
||||
aRelPath = aFileName.substr( tagpos + 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool getHollerith( const std::string& aString, size_t& aIndex, wxString& aResult )
|
||||
{
|
||||
aResult.clear();
|
||||
|
||||
if( aIndex < 0 || aIndex >= aString.size() )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "bad Hollerith string on line" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t i2 = aString.find( '"', aIndex );
|
||||
|
||||
if( std::string::npos == i2 )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "missing opening quote mark in config file" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
++i2;
|
||||
|
||||
if( i2 >= aString.size() )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "invalid entry (unexpected end of line)" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string tnum;
|
||||
|
||||
while( aString[i2] >= '0' && aString[i2] <= '9' )
|
||||
tnum.append( 1, aString[i2++] );
|
||||
|
||||
if( tnum.empty() || aString[i2++] != ':' )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "bad Hollerith string on line" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::istringstream istr;
|
||||
istr.str( tnum );
|
||||
size_t nchars;
|
||||
istr >> nchars;
|
||||
|
||||
if( (i2 + nchars) >= aString.size() )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "invalid entry (unexpected end of line)" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( nchars > 0 )
|
||||
{
|
||||
aResult = aString.substr( i2, nchars );
|
||||
i2 += nchars;
|
||||
}
|
||||
|
||||
if( aString[i2] != '"' )
|
||||
{
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
wxString errmsg = _( "missing closing quote mark in config file" );
|
||||
std::cerr << " * " << errmsg.ToUTF8() << "\n'" << aString << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
aIndex = i2 + 1;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -39,26 +39,22 @@
|
|||
#include <wx/string.h>
|
||||
#include "str_rsort.h"
|
||||
|
||||
struct S3D_ALIAS
|
||||
{
|
||||
wxString m_alias; // alias to the base path
|
||||
wxString m_pathvar; // base path as stored in the config file
|
||||
wxString m_pathexp; // expanded base path
|
||||
wxString m_description; // description of the aliased path
|
||||
};
|
||||
|
||||
class S3D_FILENAME_RESOLVER
|
||||
{
|
||||
private:
|
||||
wxString m_ConfigDir; // 3D configuration directory
|
||||
std::list< wxString > m_Paths; // list of base paths to search from
|
||||
std::list< S3D_ALIAS > m_Paths; // list of base paths to search from
|
||||
// mapping of (short) file names to resolved names
|
||||
std::map< wxString, wxString, S3D::rsort_wxString > m_NameMap;
|
||||
|
||||
/**
|
||||
* Function checkRealPath
|
||||
* checks if a file exists, is a regular file, and retrieves
|
||||
* the canonical name and extension.
|
||||
*
|
||||
* @param aFileName [in] is the file name and path to be checked
|
||||
* @param aResolvedName [out] is the canonical resolved filename
|
||||
* @param aFileExtension [out] is the file's extension string
|
||||
* @return true if the file was found and is a regular file
|
||||
*/
|
||||
bool checkRealPath( const wxString& aFileName, wxString& aResolvedName );
|
||||
int m_errflags;
|
||||
|
||||
/**
|
||||
* Function createPathList
|
||||
|
@ -75,10 +71,10 @@ private:
|
|||
* Function addPath
|
||||
* checks that a path is valid and adds it to the search list
|
||||
*
|
||||
* @param aPath is the path to be checked and added
|
||||
* @param aPath is the alias set to be checked and added
|
||||
* @return true if aPath is valid
|
||||
*/
|
||||
bool addPath( const wxString& aPath );
|
||||
bool addPath( const S3D_ALIAS& aPath );
|
||||
|
||||
/**
|
||||
* Function readPathList
|
||||
|
@ -99,6 +95,8 @@ private:
|
|||
bool writePathList( void );
|
||||
|
||||
public:
|
||||
S3D_FILENAME_RESOLVER();
|
||||
|
||||
/**
|
||||
* Function Set3DConfigDir
|
||||
* sets the user's configuration directory
|
||||
|
@ -127,7 +125,7 @@ public:
|
|||
* clears the current path list and substitutes the given path
|
||||
* list, updating the path configuration file on success.
|
||||
*/
|
||||
bool UpdatePathList( std::vector< wxString >& aPathList );
|
||||
bool UpdatePathList( std::vector< S3D_ALIAS >& aPathList );
|
||||
|
||||
/**
|
||||
* Function ResolvePath
|
||||
|
@ -159,7 +157,15 @@ public:
|
|||
*
|
||||
* @return pointer to the internal path list
|
||||
*/
|
||||
const std::list< wxString >* GetPaths( void );
|
||||
const std::list< S3D_ALIAS >* GetPaths( void );
|
||||
|
||||
/**
|
||||
* Function SplitAlias
|
||||
* returns true if the given name contains an alias and
|
||||
* populates the string anAlias with the alias and aRelPath
|
||||
* with the relative path.
|
||||
*/
|
||||
bool SplitAlias( const wxString& aFileName, wxString& anAlias, wxString& aRelPath );
|
||||
};
|
||||
|
||||
#endif // FILENAME_RESOLVER_3D_H
|
||||
|
|
|
@ -100,9 +100,9 @@ DLG_CFG_3DPATH::DLG_CFG_3DPATH( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResol
|
|||
|
||||
if( resolver )
|
||||
{
|
||||
const std::list< wxString >* pl = resolver->GetPaths();
|
||||
std::list< wxString >::const_iterator sL = pl->begin();
|
||||
std::list< wxString >::const_iterator eL = pl->end();
|
||||
const std::list< S3D_ALIAS >* pl = resolver->GetPaths();
|
||||
std::list< S3D_ALIAS >::const_iterator sL = pl->begin();
|
||||
std::list< S3D_ALIAS >::const_iterator eL = pl->end();
|
||||
|
||||
// always skip the first entry which is the current project dir
|
||||
if( sL != eL )
|
||||
|
@ -113,7 +113,7 @@ DLG_CFG_3DPATH::DLG_CFG_3DPATH( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResol
|
|||
while( sL != eL )
|
||||
{
|
||||
m_paths.push_back( *sL );
|
||||
pathList->InsertItem( i, *sL );
|
||||
pathList->InsertItem( i, sL->m_alias );
|
||||
++i;
|
||||
++sL;
|
||||
}
|
||||
|
@ -130,8 +130,10 @@ DLG_CFG_3DPATH::DLG_CFG_3DPATH( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResol
|
|||
|
||||
bool DLG_CFG_3DPATH::TransferDataFromWindow()
|
||||
{
|
||||
if( resolver && resolver->UpdatePathList( m_paths ) )
|
||||
return true;
|
||||
// NOTE: This dialog is to be deprecated
|
||||
|
||||
//if( resolver && resolver->UpdatePathList( m_paths ) )
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -139,6 +141,9 @@ bool DLG_CFG_3DPATH::TransferDataFromWindow()
|
|||
|
||||
void DLG_CFG_3DPATH::EditPath( wxCommandEvent& event )
|
||||
{
|
||||
// NOTE: This dialog is to be deprecated
|
||||
|
||||
/*
|
||||
long nItem = pathList->GetFirstSelected();
|
||||
wxString tmpname = m_paths[ nItem ];
|
||||
|
||||
|
@ -164,6 +169,7 @@ void DLG_CFG_3DPATH::EditPath( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
delete dd;
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -171,6 +177,9 @@ void DLG_CFG_3DPATH::EditPath( wxCommandEvent& event )
|
|||
|
||||
void DLG_CFG_3DPATH::AddPath( wxCommandEvent& event )
|
||||
{
|
||||
// NOTE: This dialog is to be deprecated
|
||||
|
||||
/*
|
||||
wxDirDialog* dd = new wxDirDialog( this, _( "Add a 3D model directory" ) );
|
||||
|
||||
if( wxID_OK == dd->ShowModal() )
|
||||
|
@ -188,6 +197,7 @@ void DLG_CFG_3DPATH::AddPath( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
delete dd;
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -195,6 +205,9 @@ void DLG_CFG_3DPATH::AddPath( wxCommandEvent& event )
|
|||
|
||||
void DLG_CFG_3DPATH::DeletePath( wxCommandEvent& event )
|
||||
{
|
||||
// NOTE: This dialog is to be deprecated
|
||||
|
||||
/*
|
||||
long nItem = pathList->GetFirstSelected();
|
||||
|
||||
if( -1 == nItem )
|
||||
|
@ -216,6 +229,7 @@ void DLG_CFG_3DPATH::DeletePath( wxCommandEvent& event )
|
|||
deleteButton->Enable( false );
|
||||
pathList->Select( -1 );
|
||||
}
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
wxButton* deleteButton;
|
||||
|
||||
S3D_FILENAME_RESOLVER* resolver;
|
||||
std::vector< wxString > m_paths;
|
||||
std::vector< S3D_ALIAS > m_paths;
|
||||
|
||||
public:
|
||||
DLG_CFG_3DPATH( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver );
|
||||
|
|
|
@ -350,14 +350,14 @@ void PANEL_PREV_3D::updateDirChoiceList( void )
|
|||
if( NULL == m_FileDlg || NULL == m_ModelManager || NULL == dirChoices )
|
||||
return;
|
||||
|
||||
std::list< wxString > const* md = m_ModelManager->GetResolver()->GetPaths();
|
||||
std::list< wxString >::const_iterator sL = md->begin();
|
||||
std::list< wxString >::const_iterator eL = md->end();
|
||||
std::list< S3D_ALIAS > const* md = m_ModelManager->GetResolver()->GetPaths();
|
||||
std::list< S3D_ALIAS >::const_iterator sL = md->begin();
|
||||
std::list< S3D_ALIAS >::const_iterator eL = md->end();
|
||||
std::vector< wxString > cl;
|
||||
|
||||
while( sL != eL )
|
||||
{
|
||||
cl.push_back( *sL );
|
||||
cl.push_back( sL->m_pathexp );
|
||||
++sL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue