92 std::vector<std::unique_ptr<FOOTPRINT>> aDefinitions,
93 const wxString& aCacheNickname,
94 const std::vector<wxString>& aSourceLibNicknames )
102 std::map<wxString, FOOTPRINT*> defByName;
104 for(
const std::unique_ptr<FOOTPRINT>& def : aDefinitions )
106 wxString
name = def->GetFPID().GetUniStringLibItemName();
108 if( !
name.IsEmpty() )
109 defByName.emplace(
name, def.get() );
113 for(
const wxString& nick : aSourceLibNicknames )
120 auto resolveSource = [&](
const FOOTPRINT* aFp,
const wxString& aName ) -> wxString
122 std::vector<wxString> candidates;
125 if( !ownNick.IsEmpty() )
126 candidates.push_back( ownNick );
128 for(
const wxString& nick : aSourceLibNicknames )
130 if( nick != ownNick )
131 candidates.push_back( nick );
134 std::vector<wxString> matches;
136 for(
const wxString& nick : candidates )
139 matches.push_back( nick );
142 return matches.size() == 1 ? matches.front() : wxString( wxEmptyString );
147 std::map<wxString, wxString> targetByKey;
148 std::set<wxString> cacheNames;
149 std::map<wxString, std::vector<FOOTPRINT*>> instancesByName;
151 auto keyOf = [](
const wxString& aNick,
const wxString& aName )
153 return aNick + wxS(
"\x1f" ) + aName;
158 wxString
name = fp->GetFPID().GetUniStringLibItemName();
163 instancesByName[
name].push_back( fp );
165 wxString key = keyOf( fp->GetFPID().GetUniStringLibNickname(),
name );
167 if( targetByKey.count( key ) )
170 wxString sourceNick = resolveSource( fp,
name );
171 targetByKey[key] = sourceNick;
173 if( sourceNick.IsEmpty() )
174 cacheNames.insert(
name );
178 std::map<wxString, FOOTPRINT*> cacheDefs;
179 std::map<wxString, std::unique_ptr<FOOTPRINT>> placedDefs;
181 for(
const wxString&
name : cacheNames )
183 if(
auto it = defByName.find(
name ); it != defByName.end() )
185 cacheDefs[
name] = it->second;
189 const std::vector<FOOTPRINT*>& instances = instancesByName[
name];
191 if( instances.empty() )
194 wxString firstSig = placedSignature( instances.front() );
196 for(
auto it = instances.begin() + 1; it != instances.end(); ++it )
198 if( placedSignature( *it ) != firstSig )
201 wxString::Format(
_(
"Imported footprint '%s' has conflicting placed "
202 "definitions; keeping the first." ),
name ),
208 std::unique_ptr<FOOTPRINT>(
static_cast<FOOTPRINT*
>( instances.front()->Clone() ) );
209 cacheDefs[
name] = placedDefs[
name].get();
213 if( !cacheDefs.empty() )
219 LIB_ID fpid = fp->GetFPID();
227 if( it == targetByKey.end() )
234 if( it->second.IsEmpty() )
236 if(
result.m_cacheNickname.IsEmpty() )
250 result.m_linkedToSource++;
259 const wxString& aCacheNickname,
const std::map<wxString, FOOTPRINT*>& aCacheDefs,
263 wxString finalPath = finalFn.GetFullPath();
264 wxString tempPath = finalPath + wxS(
".tmp" );
270 report(
m_reporter,
_(
"Cannot reconcile imported footprints: no KiCad footprint writer." ),
276 auto safeDelete = [&pi](
const wxString& aPath )
280 pi->DeleteLibrary( aPath );
291 if( wxDir::Exists( tempPath ) )
292 pi->DeleteLibrary( tempPath );
294 pi->CreateLibrary( tempPath );
296 for(
const auto& [
name, def] : aCacheDefs )
298 std::unique_ptr<FOOTPRINT>
copy(
static_cast<FOOTPRINT*
>( def->Clone() ) );
301 id.SetLibNickname( aCacheNickname );
303 copy->SetReference( wxS(
"REF**" ) );
304 pi->FootprintSave( tempPath,
copy.get() );
312 wxString::Format(
_(
"Error writing imported footprint cache '%s': %s" ),
313 aCacheNickname, ioe.
What() ),
319 if( wxDir::Exists( tempPath ) )
320 safeDelete( tempPath );
326 if( wxDir::Exists( finalPath ) )
328 if( existingIsManagedCache(
m_adapter, aCacheNickname ) )
330 safeDelete( finalPath );
335 wxString::Format(
_(
"A library already exists at '%s'; leaving imported "
336 "footprints unresolved." ), finalPath ),
338 safeDelete( tempPath );
343 if( !wxRenameFile( tempPath, finalPath,
false ) )
346 wxString::Format(
_(
"Could not publish imported footprint cache to '%s'." ),
349 safeDelete( tempPath );
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
wxString result
Test unit parsing edge cases and error handling.