+ Improved 3D file resolution behavior with respect to duplicated paths

+ Added versioning to the 3D search path configuration file
This commit is contained in:
Cirilo Bernardo 2016-01-20 08:36:26 +11:00
parent fcd89c57ed
commit 3a80de107d
4 changed files with 87 additions and 25 deletions

View File

@ -32,6 +32,8 @@
#include "3d_filename_resolver.h" #include "3d_filename_resolver.h"
// configuration file version
#define CFGFILE_VERSION 1
#define S3D_RESOLVER_CONFIG wxT( "3Dresolver.cfg" ) #define S3D_RESOLVER_CONFIG wxT( "3Dresolver.cfg" )
// flag bits used to track different one-off messages to users // flag bits used to track different one-off messages to users
@ -180,7 +182,7 @@ bool S3D_FILENAME_RESOLVER::createPathList( void )
bool S3D_FILENAME_RESOLVER::UpdatePathList( std::vector< S3D_ALIAS >& aPathList ) bool S3D_FILENAME_RESOLVER::UpdatePathList( std::vector< S3D_ALIAS >& aPathList )
{ {
while( m_Paths.size() > 1 ) while( m_Paths.size() > 2 )
m_Paths.pop_back(); m_Paths.pop_back();
size_t nI = aPathList.size(); size_t nI = aPathList.size();
@ -363,22 +365,50 @@ bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
if( aPath.m_alias.empty() || aPath.m_pathvar.empty() ) if( aPath.m_alias.empty() || aPath.m_pathvar.empty() )
return false; return false;
wxFileName path( aPath.m_pathvar, wxT( "" ) ); S3D_ALIAS tpath = aPath;
tpath.m_duplicate = false;
#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( tpath.m_pathvar, wxT( "" ) );
path.Normalize(); path.Normalize();
S3D_ALIAS tpath = aPath;
if( !path.DirExists() ) if( !path.DirExists() )
{
wxString msg = _T( "The given path does not exist" );
msg.append( wxT( "\n" ) );
msg.append( tpath.m_pathvar );
tpath.m_pathexp.clear(); tpath.m_pathexp.clear();
wxMessageBox( msg, _T( "3D model search path" ) );
}
else else
{
tpath.m_pathexp = path.GetFullPath(); 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(); wxString pname = path.GetPath();
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin(); std::list< S3D_ALIAS >::iterator sPL = m_Paths.begin();
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end(); std::list< S3D_ALIAS >::iterator ePL = m_Paths.end();
while( sPL != ePL ) while( sPL != ePL )
{ {
// aliases with the same m_pathvar are forbidden and the
// user must be forced to fix the problem in order to
// obtain good filename resolution
if( !sPL->m_pathvar.empty() && !tpath.m_pathvar.empty() if( !sPL->m_pathvar.empty() && !tpath.m_pathvar.empty()
&& !tpath.m_pathvar.Cmp( sPL->m_pathvar ) ) && !tpath.m_pathvar.Cmp( sPL->m_pathvar ) )
{ {
@ -398,6 +428,10 @@ bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
return false; return false;
} }
// aliases with the same m_pathexp are acceptable (one or both
// aliases being testes may be expanded variables) but when shortening
// names the preference is for (a) a fully specified path in m_pathvar
// then (b) the more senior alias in the list
if( !sPL->m_pathexp.empty() && !tpath.m_pathexp.empty() ) if( !sPL->m_pathexp.empty() && !tpath.m_pathexp.empty() )
{ {
if( !tpath.m_pathexp.Cmp( sPL->m_pathexp ) ) if( !tpath.m_pathexp.Cmp( sPL->m_pathexp ) )
@ -421,11 +455,16 @@ bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
msg.append( sPL->m_pathexp ); msg.append( sPL->m_pathexp );
wxMessageBox( msg, _( "Bad alias (duplicate path)" ) ); wxMessageBox( msg, _( "Bad alias (duplicate path)" ) );
return false; if( tpath.m_pathvar.StartsWith( wxT( "${" ) ) )
tpath.m_duplicate = true;
else if( sPL->m_pathvar.StartsWith( wxT( "${" ) ) )
sPL->m_duplicate = true;
} }
if( tpath.m_pathexp.find( sPL->m_pathexp ) != wxString::npos if( ( tpath.m_pathexp.find( sPL->m_pathexp ) != wxString::npos
|| sPL->m_pathexp.find( tpath.m_pathexp ) != wxString::npos ) || sPL->m_pathexp.find( tpath.m_pathexp ) != wxString::npos )
&& tpath.m_pathexp.Cmp( sPL->m_pathexp ) )
{ {
wxString msg = _( "This alias: " ); wxString msg = _( "This alias: " );
msg.append( tpath.m_alias ); msg.append( tpath.m_alias );
@ -510,6 +549,7 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
int lineno = 0; int lineno = 0;
S3D_ALIAS al; S3D_ALIAS al;
size_t idx; size_t idx;
int vnum = 0; // version number
while( cfgFile.good() ) while( cfgFile.good() )
{ {
@ -525,6 +565,17 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
continue; continue;
} }
if( 1 == lineno && cfgLine.find( "#V" ) == 0 )
{
// extract the version number and parse accordingly
if( cfgLine.size() > 2 )
{
std::istringstream istr;
istr.str( cfgLine.substr( 2 ) );
istr >> vnum;
}
}
idx = 0; idx = 0;
if( !getHollerith( cfgLine, idx, al.m_alias ) ) if( !getHollerith( cfgLine, idx, al.m_alias ) )
@ -545,6 +596,9 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
cfgFile.close(); cfgFile.close();
if( vnum < CFGFILE_VERSION )
writePathList();
if( m_Paths.size() != nitems ) if( m_Paths.size() != nitems )
return true; return true;
@ -586,6 +640,7 @@ bool S3D_FILENAME_RESOLVER::writePathList( void )
return false; return false;
} }
cfgFile << "#V" << CFGFILE_VERSION << "\n";
cfgFile.close(); cfgFile.close();
return true; return true;
} }
@ -606,6 +661,7 @@ bool S3D_FILENAME_RESOLVER::writePathList( void )
return false; return false;
} }
cfgFile << "#V" << CFGFILE_VERSION << "\n";
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin(); std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end(); std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
@ -659,25 +715,31 @@ wxString S3D_FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
size_t idx; size_t idx;
// test for files within the current project directory // test for files within the current project directory
if( !sL->m_pathexp.empty() ) // and KISYS3DMOD directory
for( int i = 0; i < 2 && sL != eL; ++i )
{ {
wxFileName fpath( sL->m_pathexp, wxT( "" ) ); if( !sL->m_pathexp.empty() )
wxString fps = fpath.GetPathWithSep();
idx = fname.find( fps );
if( std::string::npos != idx && 0 == idx )
{ {
fname = fname.substr( fps.size() ); wxFileName fpath( sL->m_pathexp, wxT( "" ) );
return fname; wxString fps = fpath.GetPathWithSep();
}
}
++sL; idx = fname.find( fps );
if( std::string::npos != idx && 0 == idx )
{
fname = fname.substr( fps.size() );
return fname;
}
}
++sL;
}
while( sL != eL ) while( sL != eL )
{ {
if( sL->m_pathexp.empty() ) // undefined paths and duplicates do not participate
// in the file name shortening procedure
if( sL->m_pathexp.empty() || sL->m_duplicate )
{ {
++sL; ++sL;
continue; continue;

View File

@ -41,6 +41,7 @@
struct S3D_ALIAS struct S3D_ALIAS
{ {
bool m_duplicate;
wxString m_alias; // alias to the base path wxString m_alias; // alias to the base path
wxString m_pathvar; // base path as stored in the config file wxString m_pathvar; // base path as stored in the config file
wxString m_pathexp; // expanded base path wxString m_pathexp; // expanded base path

View File

@ -60,8 +60,7 @@ DLG_3D_PATH_CONFIG::DLG_3D_PATH_CONFIG( wxWindow* aParent, S3D_FILENAME_RESOLVER
std::list< S3D_ALIAS >::const_iterator eL = rpaths->end(); std::list< S3D_ALIAS >::const_iterator eL = rpaths->end();
int nitems = 0; int nitems = 0;
// skip the first 2 entries which are always the current project dir // skip the current project dir and KISYS3DMOD
// and KISYS3DMOD
++sL; ++sL;
++sL; ++sL;
wxGridCellTextEditor* pEdAlias; wxGridCellTextEditor* pEdAlias;

View File

@ -357,7 +357,7 @@ void PANEL_PREV_3D::updateDirChoiceList( void )
while( sL != eL ) while( sL != eL )
{ {
if( !sL->m_pathexp.empty() ) if( !sL->m_pathexp.empty() && !sL->m_duplicate )
cl.push_back( sL->m_pathexp ); cl.push_back( sL->m_pathexp );
++sL; ++sL;