+ 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"
// configuration file version
#define CFGFILE_VERSION 1
#define S3D_RESOLVER_CONFIG wxT( "3Dresolver.cfg" )
// 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 )
{
while( m_Paths.size() > 1 )
while( m_Paths.size() > 2 )
m_Paths.pop_back();
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() )
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();
S3D_ALIAS tpath = aPath;
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();
wxMessageBox( msg, _T( "3D model search path" ) );
}
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 >::const_iterator sPL = m_Paths.begin();
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
std::list< S3D_ALIAS >::iterator sPL = m_Paths.begin();
std::list< S3D_ALIAS >::iterator ePL = m_Paths.end();
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()
&& !tpath.m_pathvar.Cmp( sPL->m_pathvar ) )
{
@ -398,6 +428,10 @@ bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
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( !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 );
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 )
&& tpath.m_pathexp.Cmp( sPL->m_pathexp ) )
{
wxString msg = _( "This alias: " );
msg.append( tpath.m_alias );
@ -510,6 +549,7 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
int lineno = 0;
S3D_ALIAS al;
size_t idx;
int vnum = 0; // version number
while( cfgFile.good() )
{
@ -525,6 +565,17 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
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;
if( !getHollerith( cfgLine, idx, al.m_alias ) )
@ -545,6 +596,9 @@ bool S3D_FILENAME_RESOLVER::readPathList( void )
cfgFile.close();
if( vnum < CFGFILE_VERSION )
writePathList();
if( m_Paths.size() != nitems )
return true;
@ -586,6 +640,7 @@ bool S3D_FILENAME_RESOLVER::writePathList( void )
return false;
}
cfgFile << "#V" << CFGFILE_VERSION << "\n";
cfgFile.close();
return true;
}
@ -606,6 +661,7 @@ bool S3D_FILENAME_RESOLVER::writePathList( void )
return false;
}
cfgFile << "#V" << CFGFILE_VERSION << "\n";
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
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;
// 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( "" ) );
wxString fps = fpath.GetPathWithSep();
idx = fname.find( fps );
if( std::string::npos != idx && 0 == idx )
if( !sL->m_pathexp.empty() )
{
fname = fname.substr( fps.size() );
return fname;
}
}
wxFileName fpath( sL->m_pathexp, wxT( "" ) );
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 )
{
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;
continue;

View File

@ -41,6 +41,7 @@
struct S3D_ALIAS
{
bool m_duplicate;
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

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();
int nitems = 0;
// skip the first 2 entries which are always the current project dir
// and KISYS3DMOD
// skip the current project dir and KISYS3DMOD
++sL;
++sL;
wxGridCellTextEditor* pEdAlias;

View File

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