Added manual editing of 3D file name with alias tags

This commit is contained in:
Cirilo Bernardo 2016-01-23 14:52:54 +11:00
parent ab2fff46f1
commit 7c829c9e84
4 changed files with 147 additions and 92 deletions

View File

@ -897,3 +897,70 @@ static bool getHollerith( const std::string& aString, size_t& aIndex, wxString&
aIndex = i2 + 1;
return true;
}
bool S3D_FILENAME_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAlias )
{
// Rules:
// 1. The generic form of an aliased 3D relative path is:
// ALIAS:relative/path
// 2. ALIAS is a UTF string excluding wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" )
// 3. The relative path must be a valid relative path for the platform
hasAlias = false;
if( aFileName.empty() )
return false;
wxString filename = aFileName;
wxString lpath;
size_t pos0 = aFileName.find( ':' );
// ensure that the file separators suit the current platform
#ifdef __WINDOWS__
filename.Replace( wxT( "/" ), wxT( "\\" ) );
// if we see the :\ pattern then it must be a drive designator
if( pos0 != wxString::npos )
{
size_t pos1 = aFileName.find( wxT( ":\\" ) ) );
if( pos1 != wxString::npos && ( pos1 != pos0 || pos1 != 1 ) )
return false;
// if we have a drive designator then we have no alias
if( pos1 != wxString::npos )
pos0 = wxString::npos;
}
#else
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
// names may not end with ':'
if( pos0 == aFileName.length() -1 )
return false;
if( pos0 != wxString::npos )
{
// ensure the alias component is not empty
if( pos0 == 0 )
return false;
lpath = filename.substr( 0, pos0 );
if( wxString::npos != lpath.find_first_of( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) ) )
return false;
hasAlias = true;
lpath = aFileName.substr( pos0 + 1 );
}
else
{
lpath = aFileName;
}
if( wxString::npos != lpath.find_first_of( wxFileName::GetForbiddenChars() ) )
return false;
return true;
}

View File

@ -167,6 +167,13 @@ public:
* with the relative path.
*/
bool SplitAlias( const wxString& aFileName, wxString& anAlias, wxString& aRelPath );
/**
* Function ValidateName
* returns true if the given path is a valid aliased relative path.
* If the path contains an alias then hasAlias is set true.
*/
bool ValidateFileName( const wxString& aFileName, bool& hasAlias );
};
#endif // FILENAME_RESOLVER_3D_H

View File

@ -354,6 +354,14 @@ void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
m_3D_ShapeNameListBox->SetSelection( m_LastSelected3DShapeIndex );
Transfert3DValuesToDisplay( m_Shapes3D_list[m_LastSelected3DShapeIndex] );
}
else
{
S3D_INFO params;
params.scale.x = 1.0;
params.scale.y = 1.0;
params.scale.z = 1.0;
m_PreviewPane->SetModelData( &params );
}
// We have modified the UI, so call Fit() for m_Panel3D
// to be sure the m_Panel3D sizers are initiliazed before opening the dialog
@ -481,64 +489,43 @@ void DIALOG_MODULE_BOARD_EDITOR::Edit3DShapeFileName()
// ensure any updated parameters are not discarded
TransfertDisplayTo3DValues( idx );
PROJECT& prj = Prj();
S3D_INFO model;
// Edit filename
wxString filename = m_3D_ShapeNameListBox->GetStringSelection();
wxTextEntryDialog dlg( this, wxEmptyString, wxEmptyString, filename );
wxString oldPath = m_Shapes3D_list[idx]->GetShape3DFullFilename();
wxString initialpath;
bool hasAlias;
S3D_FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
if( !oldPath.empty() )
if( dlg.ShowModal() != wxID_OK )
return;
filename = dlg.GetValue();
if( filename.empty() )
return;
if( !res->ValidateFileName( filename, hasAlias ) )
{
wxFileName fname( oldPath );
initialpath = fname.GetPath();
}
else
{
initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
}
wxString msg = _( "Invalid filename: " );
msg.append( filename );
wxMessageBox( msg, _T( "Edit 3D file name" ) );
int filter = 0;
wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );
if( !sidx.empty() )
{
long tmp;
sidx.ToLong( &tmp );
if( tmp > 0 && tmp <= 0x7FFFFFFF )
filter = (int) tmp;
}
if( !S3D::Select3DModel( this, Prj().Get3DCacheManager(),
initialpath, filter, &model ) )
{
return;
}
prj.SetRString( PROJECT::VIEWER_3D_PATH, initialpath );
sidx = wxString::Format( wxT( "%i" ), filter );
prj.SetRString( PROJECT::VIEWER_3D_FILTER_INDEX, sidx );
wxString alias;
wxString shortPath;
S3D_FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
oldPath = model.filename;
m_3D_ShapeNameListBox->SetString( idx, filename );
if( res && res->SplitAlias( oldPath, alias, shortPath ) )
{
oldPath = alias;
oldPath.append( wxT( ":" ) );
oldPath.append( shortPath );
}
// if the user has specified an alias in the name then prepend ':'
if( hasAlias )
filename.insert( 0, wxT( ":" ) );
m_3D_ShapeNameListBox->SetString( idx, oldPath );
#ifdef __WINDOWS__
#ifdef __WINDOWS__
// In Kicad files, filenames and paths are stored using Unix notation
model.filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
S3D_MASTER* new3DShape = new S3D_MASTER( NULL );
new3DShape->SetShape3DName( model.filename );
new3DShape->SetShape3DName( filename );
new3DShape->m_MatPosition = m_Shapes3D_list[idx]->m_MatPosition;
new3DShape->m_MatRotation = m_Shapes3D_list[idx]->m_MatRotation;
new3DShape->m_MatScale = m_Shapes3D_list[idx]->m_MatScale;
@ -555,6 +542,9 @@ void DIALOG_MODULE_BOARD_EDITOR::BrowseAndAdd3DShapeFile()
{
PROJECT& prj = Prj();
S3D_INFO model;
model.scale.x = 1.0;
model.scale.y = 1.0;
model.scale.z = 1.0;
wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );

View File

@ -225,6 +225,14 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
}
else
{
S3D_INFO params;
params.scale.x = 1.0;
params.scale.y = 1.0;
params.scale.z = 1.0;
m_PreviewPane->SetModelData( &params );
}
// We have modified the UI, so call Fit() for m_Panel3D
// to be sure the m_Panel3D sizers are initialized before opening the dialog
@ -348,69 +356,49 @@ void DIALOG_MODULE_MODULE_EDITOR::Edit3DShapeFileName()
// ensure any updated parameters are not discarded
TransfertDisplayTo3DValues( idx );
PROJECT& prj = Prj();
S3D_INFO model;
// Edit filename
wxString filename = m_3D_ShapeNameListBox->GetStringSelection();
wxTextEntryDialog dlg( this, wxEmptyString, wxEmptyString, filename );
wxString oldPath = m_shapes3D_list[idx]->GetShape3DFullFilename();
wxString initialpath;
bool hasAlias;
S3D_FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
if( !oldPath.empty() )
if( dlg.ShowModal() != wxID_OK )
return;
filename = dlg.GetValue();
if( filename.empty() )
return;
if( !res->ValidateFileName( filename, hasAlias ) )
{
wxFileName fname( oldPath );
initialpath = fname.GetPath();
}
else
{
initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
}
wxString msg = _( "Invalid filename: " );
msg.append( filename );
wxMessageBox( msg, _T( "Edit 3D file name" ) );
int filter = 0;
wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );
if( !sidx.empty() )
{
long tmp;
sidx.ToLong( &tmp );
if( tmp > 0 && tmp <= 0x7FFFFFFF )
filter = (int) tmp;
}
if( !S3D::Select3DModel( this, Prj().Get3DCacheManager(),
initialpath, filter, &model ) )
{
return;
}
prj.SetRString( PROJECT::VIEWER_3D_PATH, initialpath );
sidx = wxString::Format( wxT( "%i" ), filter );
prj.SetRString( PROJECT::VIEWER_3D_FILTER_INDEX, sidx );
wxString alias;
wxString shortPath;
S3D_FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
oldPath = model.filename;
m_3D_ShapeNameListBox->SetString( idx, filename );
if( res && res->SplitAlias( oldPath, alias, shortPath ) )
{
oldPath = alias;
oldPath.append( wxT( ":" ) );
oldPath.append( shortPath );
}
// if the user has specified an alias in the name then prepend ':'
if( hasAlias )
filename.insert( 0, wxT( ":" ) );
m_3D_ShapeNameListBox->SetString( idx, oldPath );
#ifdef __WINDOWS__
#ifdef __WINDOWS__
// In Kicad files, filenames and paths are stored using Unix notation
model.filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
S3D_MASTER* new3DShape = new S3D_MASTER( NULL );
new3DShape->SetShape3DName( model.filename );
new3DShape->SetShape3DName( filename );
new3DShape->m_MatPosition = m_shapes3D_list[idx]->m_MatPosition;
new3DShape->m_MatRotation = m_shapes3D_list[idx]->m_MatRotation;
new3DShape->m_MatScale = m_shapes3D_list[idx]->m_MatScale;
delete m_shapes3D_list[idx];
m_shapes3D_list[idx] = new3DShape;
Transfert3DValuesToDisplay( m_shapes3D_list[idx] );
return;
@ -421,6 +409,9 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DShapeFile()
{
PROJECT& prj = Prj();
S3D_INFO model;
model.scale.x = 1.0;
model.scale.y = 1.0;
model.scale.z = 1.0;
wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );