diff --git a/common/dialogs/panel_embedded_files.cpp b/common/dialogs/panel_embedded_files.cpp index 96861efad2..14dd5039fc 100644 --- a/common/dialogs/panel_embedded_files.cpp +++ b/common/dialogs/panel_embedded_files.cpp @@ -21,6 +21,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include +#include #include #include #include @@ -192,6 +194,51 @@ bool PANEL_EMBEDDED_FILES::TransferDataToWindow() bool PANEL_EMBEDDED_FILES::TransferDataFromWindow() { + std::optional deleteReferences; + + auto confirmDelete = + [&]() -> bool + { + if( EDA_ITEM* parent = dynamic_cast( 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 files; diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index b58f69c34f..a826d1018b 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -936,6 +936,18 @@ const EMBEDDED_FILES* SCHEMATIC::GetEmbeddedFiles() const } +void SCHEMATIC::RunOnNestedEmbeddedFiles( const std::function& 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 SCHEMATIC::GetFonts() const { std::set fonts; diff --git a/eeschema/schematic.h b/eeschema/schematic.h index d6b20e1fb8..f440586e5b 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -379,6 +379,8 @@ public: */ void RemoveAllListeners(); + void RunOnNestedEmbeddedFiles( const std::function& aFunction ) override; + /** * Embed fonts in the schematic. */ diff --git a/include/embedded_files.h b/include/embedded_files.h index fa853ed930..1c7e08d8ca 100644 --- a/include/embedded_files.h +++ b/include/embedded_files.h @@ -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& aFunction ) + { + } + /** * Helper function to get a list of fonts for fontconfig to add to the library. * diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 3e17d8b324..f72e798357 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -1116,23 +1116,31 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector< } -void BOARD::FixupEmbeddedData() +void BOARD::RunOnNestedEmbeddedFiles( const std::function& 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; + } + } + } ); } diff --git a/pcbnew/board.h b/pcbnew/board.h index 375be9815c..2ac10df4d1 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -474,6 +474,8 @@ public: */ void FixupEmbeddedData(); + void RunOnNestedEmbeddedFiles( const std::function& aFunction ) override; + void CacheTriangulation( PROGRESS_REPORTER* aReporter = nullptr, const std::vector& aZones = {} );