Pcbnew: footprint library table fixes.

* Replace illegal file system characters when reading legacy libraries to
  prevent FPID parsing errors and allow saving to PRETTY file format.
* Create validator to filter illegal file system characters from footprint
  name text edit controls to prevent issues when saving to PRETTY file format.
* Add missing source file licenses and some minor coding policy fixes.
This commit is contained in:
Wayne Stambaugh 2013-11-29 13:29:41 -05:00
parent 48f9ea2287
commit 56e2df79f6
9 changed files with 280 additions and 75 deletions

View File

@ -1,3 +1,26 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/** /**
* @file string.cpp * @file string.cpp
* @brief Some useful functions to handle strings. * @brief Some useful functions to handle strings.
@ -5,9 +28,18 @@
#include <fctsys.h> #include <fctsys.h>
#include <macros.h> #include <macros.h>
#include <richio.h> // StrPrintf
#include <kicad_string.h> #include <kicad_string.h>
/**
* Illegal file name characters used to insure file names will be valid on all supported
* platforms. This is the list of illegal file name characters for Windows which includes
* the illegal file name characters for Linux and OSX.
*/
static const char illegalFileNameChars[] = "\\/:\"<>|";
int ReadDelimitedText( wxString* aDest, const char* aSource ) int ReadDelimitedText( wxString* aDest, const char* aSource )
{ {
std::string utf8; // utf8 but without escapes and quotes. std::string utf8; // utf8 but without escapes and quotes.
@ -414,3 +446,34 @@ int SplitString( wxString strToSplit,
return 0; return 0;
} }
wxString GetIllegalFileNameWxChars()
{
return FROM_UTF8( illegalFileNameChars );
}
bool ReplaceIllegalFileNameChars( std::string* aName )
{
bool changed = false;
std::string result;
for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
{
if( strchr( illegalFileNameChars, *it ) )
{
StrPrintf( &result, "%%%02x", *it );
changed = true;
}
else
{
result += *it;
}
}
if( changed )
*aName = result;
return changed;
}

48
common/validators.cpp Normal file
View File

@ -0,0 +1,48 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file validators.cpp
* @brief Custom text control validator implementations.
*/
#include <kicad_string.h>
#include <validators.h>
FOOTPRINT_NAME_VALIDATOR::FOOTPRINT_NAME_VALIDATOR( wxString* aValue ) :
wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, aValue )
{
// The Windows (DOS) file system forbidden characters already include the forbidden
// file name characters for both Posix and OSX systems. The characters \/*?|"<> are
// illegal and filtered by the validator.
wxString illegalChars = GetIllegalFileNameWxChars();
wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
wxArrayString illegalCharList;
for( unsigned i = 0; i < illegalChars.size(); i++ )
illegalCharList.Add( wxString( illegalChars[i] ) );
SetExcludes( illegalCharList );
}

View File

@ -1,6 +1,27 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/** /**
* This file is part of the common library \n
* Custom string manipulation routines.
* @file kicad_string.h * @file kicad_string.h
* @see common.h, string.cpp * @see common.h, string.cpp
*/ */
@ -10,6 +31,7 @@
#define KICAD_STRING_H_ #define KICAD_STRING_H_
#include <wx/string.h> #include <wx/string.h>
#include <wx/filename.h>
/** /**
@ -57,7 +79,7 @@ std::string EscapedUTF8( const wxString& aString );
char* GetLine( FILE* aFile, char* Line, int* LineNum = NULL, int SizeLine = 255 ); char* GetLine( FILE* aFile, char* Line, int* LineNum = NULL, int SizeLine = 255 );
/** /**
* Funxtion StrPurge * Function StrPurge
* removes leading and training spaces, tabs and end of line chars in \a text * removes leading and training spaces, tabs and end of line chars in \a text
* return a pointer on the first n char in text * return a pointer on the first n char in text
*/ */
@ -79,7 +101,7 @@ wxString DateAndTime();
* *
* @param aString1 A wxChar pointer to the reference string. * @param aString1 A wxChar pointer to the reference string.
* @param aString2 A wxChar pointer to the comparison string. * @param aString2 A wxChar pointer to the comparison string.
* @param aLength The numbere of characters to compare. Set to -1 to compare * @param aLength The number of characters to compare. Set to -1 to compare
* the entire string. * the entire string.
* @param aIgnoreCase Use true to make the comparison case insensitive. * @param aIgnoreCase Use true to make the comparison case insensitive.
* @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if * @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if
@ -121,4 +143,25 @@ int SplitString( wxString strToSplit,
wxString* strDigits, wxString* strDigits,
wxString* strEnd ); wxString* strEnd );
/**
* Function GetIllegalFileNameWxChars
* @return a wString object containing the illegal file name characters for all platforms.
*/
wxString GetIllegalFileNameWxChars();
/**
* Function ReplaceIllegalFileNameChars
* checks \a aName for illegal file name characters.
*
* The Windows (DOS) file system forbidden characters already include the forbidden file
* name characters for both Posix and OSX systems. The characters \/?*|"\<\> are illegal
* and are replaced with %xx where xx the hexadecimal equivalent of the replaced character.
* This replacement may not be as elegant as using an underscore ('_') or hyphen ('-') but
* it guarentees that there will be no naming conflicts when fixing footprint library names.
*
* @param aName is a point to a std::string object containing the footprint name to verify.
* @return true if any characters have been replaced in \a aName.
*/
bool ReplaceIllegalFileNameChars( std::string* aName );
#endif // KICAD_STRING_H_ #endif // KICAD_STRING_H_

57
include/validators.h Normal file
View File

@ -0,0 +1,57 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file validators.h
* @brief Custom text control validator definitions.
*/
#include <wx/valtext.h>
/**
* Class FOOTPRINT_NAME_VALIDATOR
*
* This class provides a custom wxValidator object for limiting the allowable characters when
* defining footprint names. Since the introduction of the PRETTY footprint library format,
* footprint names cannot have any characters that would prevent file creation on any platform.
*/
class FOOTPRINT_NAME_VALIDATOR : public wxTextValidator
{
public:
FOOTPRINT_NAME_VALIDATOR( wxString* aValue = NULL ) :
wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, aValue )
{
// The Windows (DOS) file system forbidden characters already include the forbidden
// file name characters for both Posix and OSX systems. The characters \/*?|"<> are
// illegal and filtered by the validator.
wxString illegalChars = wxFileName::GetForbiddenChars( wxPATH_DOS );
wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
wxArrayString illegalCharList;
for( unsigned i = 0; i < illegalChars.size(); i++ )
illegalCharList.Add( wxString( illegalChars[i] ) );
SetExcludes( illegalCharList );
}
};

View File

@ -42,6 +42,8 @@
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <base_units.h> #include <base_units.h>
#include <macros.h> #include <macros.h>
#include <validators.h>
#include <kicad_string.h>
#include <class_module.h> #include <class_module.h>
#include <class_text_mod.h> #include <class_text_mod.h>
@ -62,6 +64,7 @@ DIALOG_MODULE_MODULE_EDITOR::DIALOG_MODULE_MODULE_EDITOR( FOOTPRINT_EDIT_FRAME*
icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) ); icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
SetIcon( icon ); SetIcon( icon );
m_FootprintNameCtrl->SetValidator( FOOTPRINT_NAME_VALIDATOR() );
initModeditProperties(); initModeditProperties();
m_sdbSizerStdButtonsOK->SetDefault(); m_sdbSizerStdButtonsOK->SetDefault();
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
@ -100,15 +103,15 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
S3D_MASTER* draw3DCopy = new S3D_MASTER(NULL); S3D_MASTER* draw3DCopy = new S3D_MASTER(NULL);
draw3DCopy->Copy( draw3D ); draw3DCopy->Copy( draw3D );
m_shapes3D_list.push_back( draw3DCopy ); m_shapes3D_list.push_back( draw3DCopy );
m_3D_ShapeNameListBox->Append(draw3DCopy->m_Shape3DName); m_3D_ShapeNameListBox->Append( draw3DCopy->m_Shape3DName );
} }
draw3D = (S3D_MASTER*) draw3D->Next(); draw3D = (S3D_MASTER*) draw3D->Next();
} }
m_DocCtrl->SetValue( m_currentModule->GetDescription() ); m_DocCtrl->SetValue( m_currentModule->GetDescription() );
m_KeywordCtrl->SetValue( m_currentModule->GetKeywords() ); m_KeywordCtrl->SetValue( m_currentModule->GetKeywords() );
m_referenceCopy = new TEXTE_MODULE(NULL); m_referenceCopy = new TEXTE_MODULE( NULL );
m_valueCopy = new TEXTE_MODULE(NULL); m_valueCopy = new TEXTE_MODULE( NULL );
m_referenceCopy->Copy( &m_currentModule->Reference() ); m_referenceCopy->Copy( &m_currentModule->Reference() );
m_valueCopy->Copy( &m_currentModule->Value() ); m_valueCopy->Copy( &m_currentModule->Value() );
m_ReferenceCtrl->SetValue( m_referenceCopy->GetText() ); m_ReferenceCtrl->SetValue( m_referenceCopy->GetText() );
@ -147,7 +150,6 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Disable hotkey move commands and Auto Placement" ) ); m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Disable hotkey move commands and Auto Placement" ) );
m_CostRot90Ctrl->SetValue( m_currentModule->GetPlacementCost90() ); m_CostRot90Ctrl->SetValue( m_currentModule->GetPlacementCost90() );
m_CostRot180Ctrl->SetValue( m_currentModule->GetPlacementCost180() ); m_CostRot180Ctrl->SetValue( m_currentModule->GetPlacementCost180() );
// Initialize 3D parameters // Initialize 3D parameters
@ -168,7 +170,7 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_currentModule->GetLocalSolderPasteMargin() ); PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_currentModule->GetLocalSolderPasteMargin() );
if( m_currentModule->GetLocalSolderPasteMargin() == 0 ) if( m_currentModule->GetLocalSolderPasteMargin() == 0 )
m_SolderPasteMarginCtrl->SetValue( wxT("-") + m_SolderPasteMarginCtrl->GetValue() ); m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 ) if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 )
msg.Printf( wxT( "-%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 ); msg.Printf( wxT( "-%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
@ -179,12 +181,11 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
// Add solder paste margin ration in per cent // Add solder paste margin ration in per cent
// for the usual default value 0.0, display -0.0 (or -0,0 in some countries) // for the usual default value 0.0, display -0.0 (or -0,0 in some countries)
msg.Printf( wxT( "%f" ), msg.Printf( wxT( "%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 && if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 &&
msg[0] == '0') // Sometimes Printf adds a sign if the value is very small (0.0) msg[0] == '0') // Sometimes Printf adds a sign if the value is very small (0.0)
m_SolderPasteMarginRatioCtrl->SetValue( wxT("-") + msg ); m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
else else
m_SolderPasteMarginRatioCtrl->SetValue( msg ); m_SolderPasteMarginRatioCtrl->SetValue( msg );
@ -208,9 +209,7 @@ void DIALOG_MODULE_MODULE_EDITOR::Transfert3DValuesToDisplay( S3D_MASTER * aStru
if( aStruct3DSource ) if( aStruct3DSource )
{ {
m_3D_Scale->SetValue( aStruct3DSource->m_MatScale ); m_3D_Scale->SetValue( aStruct3DSource->m_MatScale );
m_3D_Offset->SetValue( aStruct3DSource->m_MatPosition ); m_3D_Offset->SetValue( aStruct3DSource->m_MatPosition );
m_3D_Rotation->SetValue( aStruct3DSource->m_MatRotation ); m_3D_Rotation->SetValue( aStruct3DSource->m_MatRotation );
} }
else else
@ -221,6 +220,7 @@ void DIALOG_MODULE_MODULE_EDITOR::Transfert3DValuesToDisplay( S3D_MASTER * aStru
} }
} }
/** Copy 3D info displayed in dialog box to values in a item in m_shapes3D_list /** Copy 3D info displayed in dialog box to values in a item in m_shapes3D_list
* @param aIndexSelection = item index in m_shapes3D_list * @param aIndexSelection = item index in m_shapes3D_list
*/ */
@ -240,6 +240,7 @@ void DIALOG_MODULE_MODULE_EDITOR::On3DShapeNameSelected(wxCommandEvent& event)
{ {
if( m_lastSelected3DShapeIndex >= 0 ) if( m_lastSelected3DShapeIndex >= 0 )
TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex ); TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetSelection(); m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetSelection();
if( m_lastSelected3DShapeIndex < 0 ) // happens under wxGTK when deleting an item in m_3D_ShapeNameListBox wxListBox if( m_lastSelected3DShapeIndex < 0 ) // happens under wxGTK when deleting an item in m_3D_ShapeNameListBox wxListBox
@ -247,10 +248,11 @@ void DIALOG_MODULE_MODULE_EDITOR::On3DShapeNameSelected(wxCommandEvent& event)
if( m_lastSelected3DShapeIndex >= (int)m_shapes3D_list.size() ) if( m_lastSelected3DShapeIndex >= (int)m_shapes3D_list.size() )
{ {
wxMessageBox(wxT("On3DShapeNameSelected() error")); wxMessageBox( wxT( "On3DShapeNameSelected() error" ) );
m_lastSelected3DShapeIndex = -1; m_lastSelected3DShapeIndex = -1;
return; return;
} }
Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] ); Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
} }
@ -261,18 +263,19 @@ void DIALOG_MODULE_MODULE_EDITOR::Remove3DShape(wxCommandEvent& event)
TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex ); TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
int ii = m_3D_ShapeNameListBox->GetSelection(); int ii = m_3D_ShapeNameListBox->GetSelection();
if( ii < 0 ) if( ii < 0 )
return; return;
m_shapes3D_list.erase(m_shapes3D_list.begin() + ii ); m_shapes3D_list.erase( m_shapes3D_list.begin() + ii );
m_3D_ShapeNameListBox->Delete(ii); m_3D_ShapeNameListBox->Delete( ii );
if( m_3D_ShapeNameListBox->GetCount() == 0) if( m_3D_ShapeNameListBox->GetCount() == 0)
Transfert3DValuesToDisplay( NULL ); Transfert3DValuesToDisplay( NULL );
else else
{ {
m_lastSelected3DShapeIndex = 0; m_lastSelected3DShapeIndex = 0;
m_3D_ShapeNameListBox->SetSelection(m_lastSelected3DShapeIndex); m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] ); Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
} }
} }
@ -284,6 +287,7 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event )
wxString fullpath; wxString fullpath;
fullpath = wxGetApp().ReturnLastVisitedLibraryPath( LIB3D_PATH ); fullpath = wxGetApp().ReturnLastVisitedLibraryPath( LIB3D_PATH );
#ifdef __WINDOWS__ #ifdef __WINDOWS__
fullpath.Replace( wxT( "/" ), wxT( "\\" ) ); fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
#endif #endif
@ -313,6 +317,7 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event )
shortfilename = wxGetApp().ReturnFilenameWithRelativePathInLibPath( fullfilename ); shortfilename = wxGetApp().ReturnFilenameWithRelativePathInLibPath( fullfilename );
wxFileName aux = shortfilename; wxFileName aux = shortfilename;
if( aux.IsAbsolute() ) if( aux.IsAbsolute() )
{ // Absolute path, ask if the user wants a relative one { // Absolute path, ask if the user wants a relative one
int diag = wxMessageBox( int diag = wxMessageBox(
@ -322,12 +327,13 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event )
if( diag == wxYES ) if( diag == wxYES )
{ // Make it relative { // Make it relative
aux.MakeRelativeTo( wxT(".") ); aux.MakeRelativeTo( wxT( "." ) );
shortfilename = aux.GetPathWithSep() + aux.GetFullName(); shortfilename = aux.GetPathWithSep() + aux.GetFullName();
} }
} }
S3D_MASTER* new3DShape = new S3D_MASTER(NULL); S3D_MASTER* new3DShape = new S3D_MASTER(NULL);
#ifdef __WINDOWS__ #ifdef __WINDOWS__
// Store filename in Unix notation // Store filename in Unix notation
shortfilename.Replace( wxT( "\\" ), wxT( "/" ) ); shortfilename.Replace( wxT( "\\" ), wxT( "/" ) );
@ -341,7 +347,7 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event )
TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex ); TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetCount() - 1; m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetCount() - 1;
m_3D_ShapeNameListBox->SetSelection(m_lastSelected3DShapeIndex); m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] ); Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
} }
@ -357,12 +363,13 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
{ {
// First, test for invalid chars in module name // First, test for invalid chars in module name
wxString footprintName = m_FootprintNameCtrl->GetValue(); wxString footprintName = m_FootprintNameCtrl->GetValue();
if( ! footprintName.IsEmpty() ) if( ! footprintName.IsEmpty() )
{ {
if( ! MODULE::IsLibNameValid( footprintName ) ) if( ! MODULE::IsLibNameValid( footprintName ) )
{ {
wxString msg; wxString msg;
msg.Printf( _("Error:\none of invalid chars <%s> found\nin <%s>" ), msg.Printf( _( "Error:\none of invalid chars <%s> found\nin <%s>" ),
MODULE::ReturnStringLibNameInvalidChars( true ), MODULE::ReturnStringLibNameInvalidChars( true ),
GetChars( footprintName ) ); GetChars( footprintName ) );
@ -404,9 +411,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
// Initialize masks clearances // Initialize masks clearances
m_currentModule->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) ); m_currentModule->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
m_currentModule->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) ); m_currentModule->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
m_currentModule->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) ); m_currentModule->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
double dtmp; double dtmp;
wxString msg = m_SolderPasteMarginRatioCtrl->GetValue(); wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
@ -415,6 +420,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
// A -50% margin ratio means no paste on a pad, the ratio must be >= -50 % // A -50% margin ratio means no paste on a pad, the ratio must be >= -50 %
if( dtmp < -50.0 ) if( dtmp < -50.0 )
dtmp = -50.0; dtmp = -50.0;
// A margin ratio is always <= 0 // A margin ratio is always <= 0
if( dtmp > 0.0 ) if( dtmp > 0.0 )
dtmp = 0.0; dtmp = 0.0;
@ -423,14 +429,19 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
// Update 3D shape list // Update 3D shape list
int ii = m_3D_ShapeNameListBox->GetSelection(); int ii = m_3D_ShapeNameListBox->GetSelection();
if ( ii >= 0 ) if ( ii >= 0 )
TransfertDisplayTo3DValues( ii ); TransfertDisplayTo3DValues( ii );
S3D_MASTER* draw3D = m_currentModule->Models(); S3D_MASTER* draw3D = m_currentModule->Models();
for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ ) for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ )
{ {
S3D_MASTER* draw3DCopy = m_shapes3D_list[ii]; S3D_MASTER* draw3DCopy = m_shapes3D_list[ii];
if( draw3DCopy->m_Shape3DName.IsEmpty() ) if( draw3DCopy->m_Shape3DName.IsEmpty() )
continue; continue;
if( draw3D == NULL ) if( draw3D == NULL )
{ {
draw3D = new S3D_MASTER( draw3D ); draw3D = new S3D_MASTER( draw3D );
@ -447,6 +458,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
// Remove old extra 3D shapes // Remove old extra 3D shapes
S3D_MASTER* nextdraw3D; S3D_MASTER* nextdraw3D;
for( ; draw3D != NULL; draw3D = nextdraw3D ) for( ; draw3D != NULL; draw3D = nextdraw3D )
{ {
nextdraw3D = (S3D_MASTER*) draw3D->Next(); nextdraw3D = (S3D_MASTER*) draw3D->Next();
@ -484,4 +496,3 @@ void DIALOG_MODULE_MODULE_EDITOR::OnEditValue(wxCommandEvent& event)
m_parent->SetCrossHairPosition( tmp ); m_parent->SetCrossHairPosition( tmp );
m_ValueCtrl->SetValue( m_valueCopy->GetText() ); m_ValueCtrl->SetValue( m_valueCopy->GetText() );
} }

View File

@ -66,6 +66,7 @@ Load() TODO's
#include <fctsys.h> #include <fctsys.h>
#include <trigo.h> #include <trigo.h>
#include <macros.h> #include <macros.h>
#include <kicad_string.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <class_board.h> #include <class_board.h>
@ -94,34 +95,6 @@ typedef boost::optional<bool> opt_bool;
const wxChar* traceEaglePlugin = wxT( "KicadEaglePlugin" ); const wxChar* traceEaglePlugin = wxT( "KicadEaglePlugin" );
/// Test footprint name for kicad legality, fix if needed and return true if fixing was required.
static bool fix_eagle_package_name( string* aName )
{
string result;
bool changed = false;
for( string::iterator it = aName->begin(); it != aName->end(); ++it )
{
switch( *it )
{
case ':':
case '/':
// replace *it with %xx, as in URL encoding
StrPrintf( &result, "%%%02x", *it );
changed = true;
break;
default:
result += *it;
}
}
if( changed )
*aName = result;
return changed;
}
/// segment (element) of our XPATH into the Eagle XML document tree in PTREE form. /// segment (element) of our XPATH into the Eagle XML document tree in PTREE form.
struct TRIPLET struct TRIPLET
@ -939,7 +912,7 @@ EELEMENT::EELEMENT( CPTREE& aElement )
value = attribs.get<string>( "value" ); value = attribs.get<string>( "value" );
package = attribs.get<string>( "package" ); package = attribs.get<string>( "package" );
fix_eagle_package_name( &package ); ReplaceIllegalFileNameChars( &package );
x = attribs.get<double>( "x" ); x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" ); y = attribs.get<double>( "y" );
@ -1617,7 +1590,7 @@ void EAGLE_PLUGIN::loadLibrary( CPTREE& aLib, const string* aLibName )
string pack_name( pack_ref ); string pack_name( pack_ref );
fix_eagle_package_name( &pack_name ); ReplaceIllegalFileNameChars( &pack_name );
#if 0 && defined(DEBUG) #if 0 && defined(DEBUG)
if( pack_name == "TO220H" ) if( pack_name == "TO220H" )

View File

@ -281,6 +281,10 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
FPID fpid; FPID fpid;
std::string fpName = StrPurge( line + SZ( "$MODULE" ) ); std::string fpName = StrPurge( line + SZ( "$MODULE" ) );
// The footprint names in legacy libraries can contain the '/' and ':'
// characters which will cause the FPID parser to choke.
ReplaceIllegalFileNameChars( &fpName );
if( !fpName.empty() ) if( !fpName.empty() )
fpid = FPID( fpName ); fpid = FPID( fpName );
@ -4031,6 +4035,10 @@ void LP_CACHE::LoadModules( LINE_READER* aReader )
std::string footprintName = StrPurge( line + SZ( "$MODULE" ) ); std::string footprintName = StrPurge( line + SZ( "$MODULE" ) );
// The footprint names in legacy libraries can contain the '/' and ':'
// characters which will cause the FPID parser to choke.
ReplaceIllegalFileNameChars( &footprintName );
// set the footprint name first thing, so exceptions can use name. // set the footprint name first thing, so exceptions can use name.
module->SetFPID( FPID( footprintName ) ); module->SetFPID( FPID( footprintName ) );

View File

@ -40,6 +40,7 @@
#include <pcbcommon.h> #include <pcbcommon.h>
#include <macros.h> #include <macros.h>
#include <fp_lib_table.h> #include <fp_lib_table.h>
#include <validators.h>
#include <class_board.h> #include <class_board.h>
#include <class_module.h> #include <class_module.h>
@ -377,7 +378,7 @@ wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary()
wxString wildcard; wxString wildcard;
wildcard << wxGetTranslation( LegacyFootprintLibPathWildcard ) << wxChar('|') wildcard << wxGetTranslation( LegacyFootprintLibPathWildcard ) << wxChar( '|' )
<< wxGetTranslation( KiCadFootprintLibPathWildcard ); << wxGetTranslation( KiCadFootprintLibPathWildcard );
// prompt user for libPath and PLUGIN (library) type // prompt user for libPath and PLUGIN (library) type
@ -845,6 +846,7 @@ MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
if( moduleName.IsEmpty() ) if( moduleName.IsEmpty() )
{ {
wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName ); wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName );
dlg.SetTextValidator( FOOTPRINT_NAME_VALIDATOR() );
if( dlg.ShowModal() != wxID_OK ) if( dlg.ShowModal() != wxID_OK )
return NULL; //Aborted by user return NULL; //Aborted by user

View File

@ -297,29 +297,29 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_NEW_MODULE: case ID_MODEDIT_NEW_MODULE:
{
Clear_Pcb( true );
GetScreen()->ClearUndoRedoList();
SetCurItem( NULL );
SetCrossHairPosition( wxPoint( 0, 0 ) );
MODULE* module = Create_1_Module( wxEmptyString );
if( module ) // i.e. if create module command not aborted
{ {
Clear_Pcb( true ); // Initialize data relative to nets and netclasses (for a new
GetScreen()->ClearUndoRedoList(); // module the defaults are used)
SetCurItem( NULL ); // This is mandatory to handle and draw pads
SetCrossHairPosition( wxPoint( 0, 0 ) ); GetBoard()->BuildListOfNets();
redraw = true;
module->SetPosition( wxPoint( 0, 0 ) );
MODULE* module = Create_1_Module( wxEmptyString ); if( GetBoard()->m_Modules )
GetBoard()->m_Modules->ClearFlags();
if( module ) // i.e. if create module command not aborted Zoom_Automatique( false );
{
// Initialize data relative to nets and netclasses (for a new
// module the defaults are used)
// This is mandatory to handle and draw pads
GetBoard()->BuildListOfNets();
redraw = true;
module->SetPosition( wxPoint( 0, 0 ) );
if( GetBoard()->m_Modules )
GetBoard()->m_Modules->ClearFlags();
Zoom_Automatique( false );
}
} }
}
break; break;
case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: