Allow deletion of nested embedded files.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20581
This commit is contained in:
Jeff Young 2025-08-04 18:59:42 +01:00
parent 7240128130
commit ea84879b06
6 changed files with 92 additions and 13 deletions

View File

@ -21,6 +21,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <eda_item.h>
#include <confirm.h>
#include <bitmaps.h>
#include <dialogs/panel_embedded_files.h>
#include <embedded_files.h>
@ -192,6 +194,51 @@ bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
bool PANEL_EMBEDDED_FILES::TransferDataFromWindow()
{
std::optional<bool> deleteReferences;
auto confirmDelete =
[&]() -> bool
{
if( EDA_ITEM* parent = dynamic_cast<EDA_ITEM*>( m_files ) )
{
if( parent->Type() == PCB_T )
{
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some footprints.\n"
"Delete from footprints as well?" ) );
}
else if( parent->Type() == SCHEMATIC_T )
{
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some symbols.\n"
"Delete from symbols as well?" ) );
}
}
wxFAIL_MSG( wxT( "Unexpected embedded files owner" ) );
return false;
};
for( const auto& [name, file] : m_files->EmbeddedFileMap() )
{
if( !m_localFiles->HasFile( name ) )
{
m_files->RunOnNestedEmbeddedFiles(
[&]( EMBEDDED_FILES* nested_files )
{
if( nested_files->HasFile( name ) )
{
if( !deleteReferences.has_value() )
deleteReferences = confirmDelete();
if( deleteReferences.value() )
nested_files->RemoveFile( name, true );
}
} );
}
if( deleteReferences.has_value() && deleteReferences.value() == false )
break;
}
m_files->ClearEmbeddedFiles();
std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;

View File

@ -936,6 +936,18 @@ const EMBEDDED_FILES* SCHEMATIC::GetEmbeddedFiles() const
}
void SCHEMATIC::RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
{
SCH_SCREENS screens( Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
{
for( auto& [name, libSym] : screen->GetLibSymbols() )
aFunction( libSym->GetEmbeddedFiles() );
}
}
std::set<KIFONT::OUTLINE_FONT*> SCHEMATIC::GetFonts() const
{
std::set<KIFONT::OUTLINE_FONT*> fonts;

View File

@ -379,6 +379,8 @@ public:
*/
void RemoveAllListeners();
void RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction ) override;
/**
* Embed fonts in the schematic.
*/

View File

@ -175,6 +175,14 @@ public:
return m_files.empty();
}
/**
* Provide access to nested embedded files, such as symbols in schematics and footprints in
* boards.
*/
virtual void RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
{
}
/**
* Helper function to get a list of fonts for fontconfig to add to the library.
*

View File

@ -1116,23 +1116,31 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<
}
void BOARD::FixupEmbeddedData()
void BOARD::RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
{
for( FOOTPRINT* footprint : m_footprints )
{
for( auto& [filename, embeddedFile] : footprint->EmbeddedFileMap() )
{
EMBEDDED_FILES::EMBEDDED_FILE* file = GetEmbeddedFile( filename );
aFunction( footprint->GetEmbeddedFiles() );
}
if( file )
void BOARD::FixupEmbeddedData()
{
RunOnNestedEmbeddedFiles(
[&]( EMBEDDED_FILES* nested )
{
embeddedFile->compressedEncodedData = file->compressedEncodedData;
embeddedFile->decompressedData = file->decompressedData;
embeddedFile->data_hash = file->data_hash;
embeddedFile->is_valid = file->is_valid;
}
}
}
for( auto& [filename, embeddedFile] : nested->EmbeddedFileMap() )
{
EMBEDDED_FILES::EMBEDDED_FILE* file = GetEmbeddedFile( filename );
if( file )
{
embeddedFile->compressedEncodedData = file->compressedEncodedData;
embeddedFile->decompressedData = file->decompressedData;
embeddedFile->data_hash = file->data_hash;
embeddedFile->is_valid = file->is_valid;
}
}
} );
}

View File

@ -474,6 +474,8 @@ public:
*/
void FixupEmbeddedData();
void RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction ) override;
void CacheTriangulation( PROGRESS_REPORTER* aReporter = nullptr,
const std::vector<ZONE*>& aZones = {} );