Handle separate parsing rules for ID_SCH and ID_PCB.

This removes the existing constructors so that all parsing must
be explicit and callers are made aware that they need to think
about illegal characters, malformed ids, etc.

Fixes: lp:1783474
* https://bugs.launchpad.net/kicad/+bug/1783474
This commit is contained in:
Jeff Young 2018-07-26 15:38:30 +01:00
parent 9ec6efbf13
commit cb61525394
34 changed files with 167 additions and 182 deletions

View File

@ -56,17 +56,16 @@ FOOTPRINT_INFO* FOOTPRINT_LIST::GetModuleInfo( const wxString& aFootprintName )
if( aFootprintName.IsEmpty() )
return NULL;
LIB_ID fpid;
wxCHECK_MSG( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0, NULL,
wxString::Format( wxT( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) );
wxString libNickname = fpid.GetLibNickname();
wxString footprintName = fpid.GetLibItemName();
for( auto& fp : m_list )
{
LIB_ID fpid;
wxCHECK_MSG( fpid.Parse( aFootprintName ) < 0, NULL,
wxString::Format(
wxT( "\"%s\" is not a valid LIB_ID." ), GetChars( aFootprintName ) ) );
wxString libNickname = fpid.GetLibNickname();
wxString footprintName = fpid.GetLibItemName();
if( libNickname == fp->GetNickname() && footprintName == fp->GetFootprintName() )
return &*fp;
}

View File

@ -119,7 +119,7 @@ void LIB_ID::clear()
}
int LIB_ID::Parse( const UTF8& aId )
int LIB_ID::Parse( const UTF8& aId, LIB_ID_TYPE aType, bool aFix )
{
clear();
@ -127,7 +127,7 @@ int LIB_ID::Parse( const UTF8& aId )
const char* rev = EndsWithRev( buffer, buffer+aId.length(), '/' );
size_t revNdx;
size_t partNdx;
int offset;
int offset = -1;
//=====<revision>=========================================
// in a LIB_ID like discret:R3/rev4
@ -150,9 +150,7 @@ int LIB_ID::Parse( const UTF8& aId )
offset = SetLibNickname( aId.substr( 0, partNdx ) );
if( offset > -1 )
{
return offset;
}
++partNdx; // skip ':'
}
@ -165,48 +163,24 @@ int LIB_ID::Parse( const UTF8& aId )
if( partNdx >= revNdx )
return partNdx; // Error: no library item name.
UTF8 fpname = aId.substr( partNdx, revNdx-partNdx );
// Be sure the item name is valid.
// Some chars can be found in legacy files converted files from other EDA tools.
std::string fpname = aId.substr( partNdx, revNdx-partNdx );
ReplaceIllegalFileNameChars( &fpname, '_' );
SetLibItemName( UTF8( fpname ) );
if( aFix )
fpname = FixIllegalChars( fpname, aType, false );
else
offset = HasIllegalChars( fpname, aType );
if( offset > -1 )
return offset;
SetLibItemName( fpname );
return -1;
}
LIB_ID::LIB_ID( const UTF8& aId )
{
int offset = Parse( aId );
if( offset != -1 )
{
THROW_PARSE_ERROR( _( "Illegal character found in LIB_ID string" ),
wxString::FromUTF8( aId.c_str() ),
aId.c_str(),
0,
offset );
}
}
LIB_ID::LIB_ID( const wxString& aId )
{
UTF8 id = aId;
int offset = Parse( id );
if( offset != -1 )
{
THROW_PARSE_ERROR( _( "Illegal character found in LIB_ID string" ),
aId,
id.c_str(),
0,
offset );
}
}
LIB_ID::LIB_ID( const wxString& aLibName, const wxString& aLibItemName,
const wxString& aRevision ) :
nickname( aLibName ),
@ -359,15 +333,19 @@ int LIB_ID::compare( const LIB_ID& aLibId ) const
}
bool LIB_ID::HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType )
int LIB_ID::HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType )
{
int offset = 0;
for( auto ch : aLibItemName )
{
if( !isLegalChar( ch, aType ) )
return true;
return offset;
else
++offset;
}
return false;
return -1;
}
@ -391,7 +369,8 @@ UTF8 LIB_ID::FixIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType, bool
bool LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType )
{
bool const colon_allowed = ( aType == ID_ALIAS );
bool const space_allowed = ( aType != ID_SCH );
bool const space_allowed = ( aType == ID_ALIAS || aType == ID_PCB );
bool const illegal_filename_chars_allowed = ( aType == ID_SCH || aType == ID_ALIAS );
if( aUniChar < ' ' )
return false;
@ -400,7 +379,10 @@ bool LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType )
{
case '/':
case '\\':
return false;
case '<':
case '>':
case '"':
return illegal_filename_chars_allowed;
case ':':
return colon_allowed;

View File

@ -429,7 +429,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
{
LIB_ID fpid;
if( fpid.Parse( aFootprintName ) >= 0 )
if( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) >= 0 )
{
DisplayInfoMessage( this, wxString::Format( _( "Footprint ID \"%s\" is not valid." ),
GetChars( aFootprintName ) ) );

View File

@ -99,9 +99,8 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
if( !aFootprintName.IsEmpty() )
{
wxCHECK_RET( fpid.Parse( aFootprintName ) < 0,
wxString::Format( _( "\"%s\" is not a valid LIB_ID." ),
GetChars( aFootprintName ) ) );
wxCHECK_RET( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0,
wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) );
}
component->SetFPID( fpid );

View File

@ -287,8 +287,7 @@ void LIB_PART::SetName( const wxString& aName )
else
m_aliases[0]->SetName( aName );
// LIB_ALIAS validates the name, reuse it instead of validating the name again
wxString validatedName( m_aliases[0]->GetName() );
wxString validatedName = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
m_libId.SetLibItemName( validatedName, false );
LIB_FIELD& valueField = GetValueField();

View File

@ -57,15 +57,15 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const
bool aShowFootprints )
: DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
m_hsplitter( nullptr ),
m_vsplitter( nullptr ),
m_fp_sel_ctrl( nullptr ),
m_fp_view_ctrl( nullptr ),
m_parent( aParent ),
m_deMorganConvert( aDeMorganConvert >= 0 ? aDeMorganConvert : 0 ),
m_allow_field_edits( aAllowFieldEdits ),
m_show_footprints( aShowFootprints ),
m_external_browser_requested( false ),
m_hsplitter( nullptr ),
m_vsplitter( nullptr )
m_external_browser_requested( false )
{
auto sizer = new wxBoxSizer( wxVERTICAL );
wxHtmlWindow* details = nullptr;
@ -325,7 +325,7 @@ void DIALOG_CHOOSE_COMPONENT::ShowFootprint( wxString const& aName )
{
LIB_ID lib_id;
if( lib_id.Parse( aName ) == -1 && lib_id.IsValid() )
if( lib_id.Parse( aName, LIB_ID::ID_PCB ) == -1 && lib_id.IsValid() )
{
m_fp_view_ctrl->ClearStatus();
m_fp_view_ctrl->CacheFootprint( lib_id );

View File

@ -301,7 +301,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnBrowseLibrary( wxCommandEvent& event
SCH_BASE_FRAME::HISTORY_LIST dummy;
LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue() );
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
auto sel = GetParent()->SelectComponentFromLibrary( nullptr, dummy, true, 0, 0, false, &id );
@ -349,7 +349,6 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnEditSpiceModel( wxCommandEvent& event
bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
{
wxString msg;
wxString tmp;
LIB_ID id;
// Commit any pending in-place edits and close the editor
@ -365,9 +364,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
return false;
}
tmp = m_libraryNameTextCtrl->GetValue();
tmp.Replace( wxT( " " ), wxT( "_" ) );
id.Parse( tmp );
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
if( !id.IsValid() )
{
@ -438,7 +435,8 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event
STATUS_FLAGS flags = m_cmp->GetFlags();
// Library symbol identifier
LIB_ID id( m_libraryNameTextCtrl->GetValue() );
LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() );
// For symbols with multiple shapes (De Morgan representation) Set the selected shape:

View File

@ -560,7 +560,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::validateLibIds()
// a new lib id is found. validate this new value
LIB_ID id;
id.Parse( new_libid );
id.Parse( new_libid, LIB_ID::ID_SCH );
if( !id.IsValid() )
{
@ -629,7 +629,8 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event )
wxString orphanLibid = m_grid->GetCellValue( m_OrphansRowIndexes[ii], COL_CURR_LIBID );
int grid_row_idx = m_OrphansRowIndexes[ii]; //row index in m_grid for the current item
LIB_ID curr_libid( orphanLibid );
LIB_ID curr_libid;
curr_libid.Parse( orphanLibid, LIB_ID::ID_SCH, true );
wxString symbName = curr_libid.GetLibItemName();
// number of full LIB_ID candidates (because we search for a symbol name
// inside all avaiable libraries, perhaps the same symbol name can be found
@ -637,7 +638,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event )
int libIdCandidateCount = 0;
candidateSymbNames.Clear();
// now try to fin a candidate
// now try to find a candidate
for( auto &lib : libs )
{
aliasNames.Clear();
@ -754,7 +755,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::TransferDataFromWindow()
// a new lib id is found and was already validated.
// set this new value
LIB_ID id;
id.Parse( new_libid );
id.Parse( new_libid, LIB_ID::ID_SCH, true );
for( CMP_CANDIDATE& cmp : m_components )
{
@ -791,7 +792,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::revertChanges()
continue;
LIB_ID id;
id.Parse( cmp.m_InitialLibId );
id.Parse( cmp.m_InitialLibId, LIB_ID::ID_SCH, true );
if( cmp.m_Component->GetLibId() != id )
{

View File

@ -96,33 +96,32 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescu
dc.SetFont( font );
int padding = 30;
int width = dc.GetTextExtent( header ).GetWidth();
m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
wxALIGN_CENTER );
header = _( "Symbol Name" );
width = dc.GetTextExtent( header ).GetWidth() + padding;
width = dc.GetTextExtent( header ).GetWidth() * 2;
m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Action Taken" );
width = dc.GetTextExtent( header ).GetWidth() + padding;
width = dc.GetTextExtent( header ).GetWidth() * 10;
m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Reference" );
width = dc.GetTextExtent( header ).GetWidth() + padding;
width = dc.GetTextExtent( header ).GetWidth() * 2;
m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Value" );
width = dc.GetTextExtent( header ).GetWidth() + padding;
width = dc.GetTextExtent( header ).GetWidth() * 10;
m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
m_componentViewOld->SetLayoutDirection( wxLayout_LeftToRight );
m_componentViewNew->SetLayoutDirection( wxLayout_LeftToRight );
Layout();
SetSizeInDU( 280, 240 );
SetSizeInDU( 480, 240 );
// Make sure the HTML window is large enough. Some fun size juggling and
// fudge factors here but it does seem to work pretty reliably.
@ -133,7 +132,7 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescu
m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
Layout();
GetSizer()->SetSizeHints( this );
SetSizeInDU( 280, 240 );
SetSizeInDU( 480, 240 );
Center();
}

View File

@ -844,7 +844,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
if( !fpField->GetText().IsEmpty() )
{
LIB_ID fpId( fpField->GetText() );
LIB_ID fpId;
fpId.Parse( fpField->GetText(), LIB_ID::ID_SCH, true );
fpId.SetLibNickname( newfilename.GetName() );
fpField->SetText( fpId.Format() );
}

View File

@ -85,7 +85,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowse
{
LIB_ID id;
if( id.Parse( symbol ) == -1 )
if( id.Parse( symbol, LIB_ID::ID_SCH ) == -1 )
sel.LibId = id;
sel.Unit = viewlibFrame->GetUnit();

View File

@ -258,10 +258,15 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
// Test whether there is a conflict or if the symbol can only be found in the cache
// and the symbol name does not have any illegal characters.
if( ( ( cache_match && lib_match
&& !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
|| (!cache_match && lib_match ) ) && !LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) )
continue;
if( LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) == -1 )
{
if( cache_match && lib_match &&
!cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
continue;
if( !cache_match && lib_match )
continue;
}
// Check if the symbol has already been rescued.
wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH );
@ -379,12 +384,14 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
continue;
// Test whether there is a conflict or if the symbol can only be found in the cache.
if( ( ( cache_match && lib_match
&& !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
|| (!cache_match && lib_match ) )
&& !LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) )
if( LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) == -1 )
{
continue;
if( cache_match && lib_match &&
!cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
continue;
if( !cache_match && lib_match )
continue;
}
// Fix illegal LIB_ID name characters.

View File

@ -1431,7 +1431,7 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
// parsing the symbol name with LIB_ID::Parse() would break symbol library links
// that contained '/' and ':' characters.
if( m_version > 3 )
libId.Parse( libName );
libId.Parse( libName, LIB_ID::ID_SCH, true );
else
libId.SetLibItemName( libName, false );

View File

@ -46,7 +46,7 @@ static void DisplayCmpDocAndKeywords( wxString& aSelection, void* aData )
LIB_ID id;
if( id.Parse( aSelection ) != -1 )
if( id.Parse( aSelection, LIB_ID::ID_SCH ) != -1 )
{
aSelection = _( "Invalid symbol library identifier!" );
return;

View File

@ -52,25 +52,15 @@ class LIB_ID
{
public:
LIB_ID() {}
/**
* Takes \a aId string and parses it.
*
* A typical LIB_ID string consists of a library nickname followed by a library item name.
* e.g.: "smt:R_0805", or
* e.g.: "mylib:R_0805", or
* e.g.: "ttl:7400"
*
* @param aId is a string to be parsed into the LIB_ID object.
*/
LIB_ID( const UTF8& aId );
LIB_ID( const wxString& aId );
///> Types of library identifiers
enum LIB_ID_TYPE { ID_SCH, ID_ALIAS, ID_PCB };
LIB_ID() {}
// NOTE: don't define any constructors which call Parse() on their arguments. We want it
// to be obvious to callers that parsing is involved (and that valid IDs are guaranteed in
// the presence of disallowed characters, malformed ids, etc.).
/**
* This LIB_ID ctor is a special version which ignores the parsing due to symbol
* names allowing '/' as a valid character. This was causing the symbol names to
@ -87,13 +77,19 @@ public:
/**
* Parse LIB_ID with the information from @a aId.
*
* A typical LIB_ID string consists of a library nickname followed by a library item name.
* e.g.: "smt:R_0805", or
* e.g.: "mylib:R_0805", or
* e.g.: "ttl:7400"
*
* @param aId is the string to populate the #LIB_ID object.
* @param aType indicates the LIB_ID type for type-specific parsing (such as allowed chars).
* @param aFix indicates invalid chars should be replaced with '_'.
*
* @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into
* aId at which an error was detected.
*/
int Parse( const UTF8& aId );
int Parse( const UTF8& aId, LIB_ID_TYPE aType, bool aFix = false );
/**
* Return the logical library name portion of a LIB_ID.
@ -209,9 +205,9 @@ public:
*
* @param aLibItemName is the #LIB_ID name to test for illegal characters.
* @param aType is the library identifier type
* @return true if \a aLibItemName contain illegal characters otherwise false.
* @return offset of first illegal character otherwise -1.
*/
static bool HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType );
static int HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType );
/**
* Replace illegal #LIB_ID item name characters with underscores '_'.

View File

@ -36,13 +36,13 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow
m_itemsGrid->SetMargins( 0, 0 );
// Columns
m_itemsGrid->SetColSize( 0, 120 );
m_itemsGrid->SetColSize( 1, 48 );
m_itemsGrid->SetColSize( 0, 116 );
m_itemsGrid->SetColSize( 1, 53 );
m_itemsGrid->SetColSize( 2, 90 );
m_itemsGrid->SetColSize( 3, 90 );
m_itemsGrid->SetColSize( 4, 90 );
m_itemsGrid->SetColSize( 5, 48 );
m_itemsGrid->SetColSize( 6, 112 );
m_itemsGrid->SetColSize( 5, 53 );
m_itemsGrid->SetColSize( 6, 106 );
m_itemsGrid->SetColSize( 7, 90 );
m_itemsGrid->SetColSize( 8, 90 );
m_itemsGrid->SetColSize( 9, 90 );
@ -424,14 +424,14 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow
m_modelsGrid->SetMargins( 0, 0 );
// Columns
m_modelsGrid->SetColSize( 0, 662 );
m_modelsGrid->SetColSize( 1, 53 );
m_modelsGrid->SetColSize( 0, 650 );
m_modelsGrid->SetColSize( 1, 65 );
m_modelsGrid->EnableDragColMove( false );
m_modelsGrid->EnableDragColSize( false );
m_modelsGrid->SetColLabelSize( 22 );
m_modelsGrid->SetColLabelValue( 0, _("3D Model(s)") );
m_modelsGrid->SetColLabelValue( 1, _("Preview") );
m_modelsGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
m_modelsGrid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_modelsGrid->EnableDragRowSize( false );

View File

@ -303,7 +303,7 @@
<property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Keep Upright&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">11</property>
<property name="column_sizes">120,48,90,90,90,48,112,90,90,90,90</property>
<property name="column_sizes">116,53,90,90,90,53,106,90,90,90,90</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
@ -4589,12 +4589,12 @@
<property name="cell_vert_alignment">wxALIGN_TOP</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_LEFT</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
<property name="col_label_size">22</property>
<property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">2</property>
<property name="column_sizes">662,53</property>
<property name="column_sizes">650,65</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>

View File

@ -36,13 +36,13 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
m_itemsGrid->SetMargins( 0, 0 );
// Columns
m_itemsGrid->SetColSize( 0, 120 );
m_itemsGrid->SetColSize( 1, 48 );
m_itemsGrid->SetColSize( 0, 116 );
m_itemsGrid->SetColSize( 1, 53 );
m_itemsGrid->SetColSize( 2, 96 );
m_itemsGrid->SetColSize( 3, 96 );
m_itemsGrid->SetColSize( 4, 96 );
m_itemsGrid->SetColSize( 5, 48 );
m_itemsGrid->SetColSize( 6, 112 );
m_itemsGrid->SetColSize( 5, 53 );
m_itemsGrid->SetColSize( 6, 106 );
m_itemsGrid->SetColSize( 7, 80 );
m_itemsGrid->SetColSize( 8, 48 );
m_itemsGrid->SetColSize( 9, 96 );
@ -332,8 +332,8 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
m_modelsGrid->SetMargins( 0, 0 );
// Columns
m_modelsGrid->SetColSize( 0, 662 );
m_modelsGrid->SetColSize( 1, 53 );
m_modelsGrid->SetColSize( 0, 650 );
m_modelsGrid->SetColSize( 1, 65 );
m_modelsGrid->EnableDragColMove( false );
m_modelsGrid->EnableDragColSize( false );
m_modelsGrid->SetColLabelSize( 22 );

View File

@ -302,7 +302,7 @@
<property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Unconstrained&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">11</property>
<property name="column_sizes">120,48,96,96,96,48,112,80,48,96,96</property>
<property name="column_sizes">116,53,96,96,96,53,106,80,48,96,96</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
@ -3734,7 +3734,7 @@
<property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">2</property>
<property name="column_sizes">662,53</property>
<property name="column_sizes">650,65</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>

View File

@ -187,6 +187,8 @@ void DIALOG_EXCHANGE_FOOTPRINTS::setMatchMode( int aMatchMode )
bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule )
{
LIB_ID specifiedID;
switch( getMatchMode() )
{
case ID_MATCH_FP_ALL:
@ -203,7 +205,8 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule )
else
return aModule->GetValue() == m_specifiedValue->GetValue();
case ID_MATCH_FP_ID:
return aModule->GetFPID() == m_specifiedID->GetValue();
specifiedID.Parse( m_specifiedID->GetValue(), LIB_ID::ID_PCB );
return aModule->GetFPID() == specifiedID;
}
return false; // just to quiet compiler warnings....
}
@ -325,7 +328,7 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::processCurrentModule()
if( newFPIDStr.IsEmpty() )
return false;
newFPID = LIB_ID( newFPIDStr );
newFPID.Parse( newFPIDStr, LIB_ID::ID_PCB, true );
}
return processModule( m_currentModule, newFPID );
@ -337,14 +340,19 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::processMatchingModules()
MODULE* Module;
MODULE* PtBack;
bool change = false;
wxString newFPID = m_newID->GetValue();
LIB_ID newFPID;
wxString value;
if( !m_parent->GetBoard()->m_Modules )
return false;
if( !m_updateMode && newFPID == wxEmptyString )
return false;
if( !m_updateMode )
{
newFPID.Parse( m_newID->GetValue(), LIB_ID::ID_PCB );
if( !newFPID.IsValid() )
return false;
}
/* The change is done from the last module because processModule() modifies the last item
* in the list.

View File

@ -52,7 +52,9 @@ DIALOG_GET_FOOTPRINT::DIALOG_GET_FOOTPRINT( PCB_BASE_FRAME* parent, bool aShowBr
for( size_t ii = 0; ii < s_HistoryList.size(); ++ii )
{
LIB_ID fpid( s_HistoryList[ ii ] );
LIB_ID fpid;
fpid.Parse( s_HistoryList[ ii ], LIB_ID::ID_PCB );
if( m_frame->CheckFootprint( fpid ) )
m_historyList->Append( s_HistoryList[ ii ] );
}

View File

@ -1346,7 +1346,9 @@ MODULE* EAGLE_PLUGIN::makeModule( wxXmlNode* aPackage, const wxString& aPkgName
{
std::unique_ptr<MODULE> m( new MODULE( m_board ) );
m->SetFPID( LIB_ID( UTF8( aPkgName ) ) );
LIB_ID fpID;
fpID.Parse( aPkgName, LIB_ID::ID_PCB, true );
m->SetFPID( fpID );
// Get the first package item and iterate
wxXmlNode* packageItem = aPackage->GetChildren();

View File

@ -550,23 +550,21 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
{
wxString msg = wxString::Format(
_( "Library \"%s\" is read only" ),
GetChars( nickname )
);
wxString msg = wxString::Format( _( "Library \"%s\" is read only" ), nickname );
DisplayError( this, msg );
return false;
}
wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname,
wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() );
LIB_ID fpid;
wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, wxEmptyString,
wxEmptyString, Prj().PcbFootprintLibs() );
if( !fpid_txt )
fpid.Parse( fpid_txt, LIB_ID::ID_PCB );
if( !fpid.IsValid() )
return false;
LIB_ID fpid( fpid_txt );
wxString fpname = fpid.GetLibItemName();
wxString fpname = fpid.GetLibItemName();
// Confirmation
wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
@ -671,7 +669,7 @@ public:
{
m_module = aModule;
m_savedFPID = aModule->GetFPID();
m_module->SetFPID( LIB_ID( m_savedFPID.GetLibItemName() ) );
m_module->SetFPID( LIB_ID( wxEmptyString, m_savedFPID.GetLibItemName() ) );
}
~LIBRARY_NAME_CLEARER()
{
@ -855,7 +853,7 @@ MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName )
module->SetLastEditTime();
// Update its name in lib
module->SetFPID( LIB_ID( moduleName ) );
module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
wxPoint default_pos;
BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();

View File

@ -621,22 +621,16 @@ bool FOOTPRINT_VIEWER_FRAME::ShowModal( wxString* aFootprint, wxWindow* aResulta
{
if( aFootprint && !aFootprint->IsEmpty() )
{
try
{
LIB_ID fpid( *aFootprint );
LIB_ID fpid;
if( fpid.IsValid() )
{
setCurNickname( fpid.GetLibNickname() );
setCurFootprintName( fpid.GetLibItemName() );
ReCreateFootprintList();
SelectAndViewFootprint( NEW_PART );
}
}
catch( ... )
fpid.Parse( *aFootprint, LIB_ID::ID_PCB, true );
if( fpid.IsValid() )
{
// LIB_ID's constructor throws on some invalid footprint IDs. It'd be nicer
// if it just set it to !IsValid(), but it is what it is.
setCurNickname( fpid.GetLibNickname() );
setCurFootprintName( fpid.GetLibItemName() );
ReCreateFootprintList();
SelectAndViewFootprint( NEW_PART );
}
}

View File

@ -232,7 +232,7 @@ MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
// any name found in the pretty file; any name in the pretty file
// must be ignored here. Also, the library nickname is unknown in
// this context so clear it just in case.
ret->SetFPID( aFootprintName );
ret->SetFPID( LIB_ID( wxEmptyString, aFootprintName ) );
return ret;
}

View File

@ -276,7 +276,7 @@ void GPCB_FPL_CACHE::Load()
MODULE* footprint = parseMODULE( &reader );
// The footprint name is the file name without the extension.
footprint->SetFPID( LIB_ID( fn.GetName() ) );
footprint->SetFPID( LIB_ID( wxEmptyString, fn.GetName() ) );
m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) );
}
catch( const IO_ERROR& ioe )

View File

@ -368,7 +368,7 @@ void KICAD_NETLIST_PARSER::parseComponent()
}
}
if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 )
{
wxString error;
error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),

View File

@ -299,7 +299,7 @@ void FP_CACHE::Load()
// The footprint name is the file name without the extension.
wxString fpName = fullPath.GetName();
footprint->SetFPID( LIB_ID( fpName ) );
footprint->SetFPID( LIB_ID( wxEmptyString, fpName ) );
m_modules.insert( fpName, new FP_CACHE_ITEM( footprint, fullPath ) );
m_cache_timestamp += fullPath.GetModificationTime().GetValue().GetValue();

View File

@ -441,7 +441,7 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
ReplaceIllegalFileNameChars( &fpName );
if( !fpName.empty() )
fpid = LIB_ID( UTF8( fpName ) );
fpid.Parse( fpName, LIB_ID::ID_PCB, true );
module->SetFPID( fpid );
@ -3317,7 +3317,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader )
ReplaceIllegalFileNameChars( &footprintName );
// set the footprint name first thing, so exceptions can use name.
module->SetFPID( LIB_ID( UTF8( footprintName ) ) );
module->SetFPID( LIB_ID( wxEmptyString, footprintName ) );
m_owner->loadMODULE( module.get() );
@ -3372,7 +3372,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader )
{
nameOK = true;
m->SetFPID( LIB_ID( UTF8( newName ) ) );
m->SetFPID( LIB_ID( wxEmptyString, newName ) );
std::pair<MODULE_ITER, bool> r = m_modules.insert( newName, m );
wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) );

View File

@ -245,9 +245,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU
LIB_ID fpid;
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ),
GetChars( moduleName ) ) );
wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) );
try
{
@ -275,9 +274,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU
}
else
{
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ),
GetChars( moduleName ) ) );
wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) );
try
{

View File

@ -345,7 +345,7 @@ MODULE* MWAVE::CreateMicrowaveInductor( INDUCTOR_PATTERN& inductorPattern,
MODULE* module = aPcbFrame->CreateNewModule( msg );
aPcbFrame->AddModuleToBoard( module );
module->SetFPID( LIB_ID( wxString( "mw_inductor" ) ) );
module->SetFPID( LIB_ID( wxEmptyString, wxT( "mw_inductor" ) ) );
module->SetAttributes( MOD_VIRTUAL | MOD_CMS );
module->ClearFlags();
module->SetPosition( inductorPattern.m_End );

View File

@ -175,7 +175,7 @@ bool CMP_READER::Load( NETLIST* aNetlist )
{
LIB_ID fpid;
if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 )
{
wxString error;
error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ),

View File

@ -520,7 +520,9 @@ void PCB_MODULE::AddToBoard()
module->SetTimeStamp( 0 );
module->SetLastEditTime( 0 );
module->SetFPID( LIB_ID( m_compRef ) );
LIB_ID fpID;
fpID.Parse( m_compRef, LIB_ID::ID_PCB, true );
module->SetFPID( fpID );
module->SetAttributes( MOD_DEFAULT | MOD_CMS );

View File

@ -1808,7 +1808,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
name = FromUTF8();
if( !name.IsEmpty() && fpid.Parse( FromUTF8() ) >= 0 )
if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 )
{
wxString error;
error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),