diff --git a/common/design_block_io.cpp b/common/design_block_io.cpp index f60926350b..0601eb2425 100644 --- a/common/design_block_io.cpp +++ b/common/design_block_io.cpp @@ -293,6 +293,9 @@ DESIGN_BLOCK* DESIGN_BLOCK_IO::DesignBlockLoad( const wxString& aLibraryPath, wxString dbPcbPath = dbPath + aDesignBlockName + wxT( "." ) + FILEEXT::KiCadPcbFileExtension; wxString dbMetadataPath = dbPath + aDesignBlockName + wxT( "." ) + FILEEXT::JsonFileExtension; + if( !wxDir::Exists( dbPath ) ) + THROW_IO_ERROR( wxString::Format( _( "Design block '%s' does not exist." ), dbPath ) ); + DESIGN_BLOCK* newDB = new DESIGN_BLOCK(); // Library name needs to be empty for when we fill it in with the correct library nickname @@ -339,16 +342,27 @@ DESIGN_BLOCK* DESIGN_BLOCK_IO::DesignBlockLoad( const wxString& aLibraryPath, } catch( ... ) { + delete newDB; THROW_IO_ERROR( wxString::Format( _( "Design block metadata file '%s' could not be read." ), dbMetadataPath ) ); } } - return newDB; } +bool DESIGN_BLOCK_IO::DesignBlockExists( const wxString& aLibraryPath, + const wxString& aDesignBlockName, + const std::map* aProperties ) +{ + wxString dbPath = aLibraryPath + wxFileName::GetPathSeparator() + aDesignBlockName + wxT( "." ) + + FILEEXT::KiCadDesignBlockPathExtension + wxFileName::GetPathSeparator(); + + return wxDir::Exists( dbPath ); +} + + void DESIGN_BLOCK_IO::DesignBlockSave( const wxString& aLibraryPath, const DESIGN_BLOCK* aDesignBlock, const std::map* aProperties ) diff --git a/common/design_block_io.h b/common/design_block_io.h index 9eb2b335ce..aa1598651b 100644 --- a/common/design_block_io.h +++ b/common/design_block_io.h @@ -76,10 +76,7 @@ public: } bool DesignBlockExists( const wxString& aLibraryPath, const wxString& aDesignBlockName, - const std::map* aProperties = nullptr ) - { - return DesignBlockLoad( aLibraryPath, aDesignBlockName, true, aProperties ) != nullptr; - } + const std::map* aProperties = nullptr ); DESIGN_BLOCK* ImportDesignBlock( const wxString& aDesignBlockPath, wxString& aDesignBlockNameOut, diff --git a/common/tool/design_block_control.cpp b/common/tool/design_block_control.cpp index fb230dd358..147cf0c796 100644 --- a/common/tool/design_block_control.cpp +++ b/common/tool/design_block_control.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include DESIGN_BLOCK_CONTROL::~DESIGN_BLOCK_CONTROL() @@ -88,9 +90,12 @@ int DESIGN_BLOCK_CONTROL::PinLibrary( const TOOL_EVENT& aEvent ) PROJECT::LIB_TYPE_T::DESIGN_BLOCK_LIB ); current->m_Pinned = true; getDesignBlockPane()->RefreshLibs(); + notifyOtherFrames(); + + return 0; } - return 0; + return -1; } @@ -104,17 +109,24 @@ int DESIGN_BLOCK_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent ) PROJECT::LIB_TYPE_T::DESIGN_BLOCK_LIB ); current->m_Pinned = false; getDesignBlockPane()->RefreshLibs(); + notifyOtherFrames(); + + return 0; } - return 0; + return -1; } int DESIGN_BLOCK_CONTROL::NewLibrary( const TOOL_EVENT& aEvent ) { - getDesignBlockPane()->CreateNewDesignBlockLibrary(); + if( getDesignBlockPane()->CreateNewDesignBlockLibrary() != wxEmptyString ) + { + notifyOtherFrames(); + return 0; + } - return 0; + return -1; } @@ -125,9 +137,13 @@ int DESIGN_BLOCK_CONTROL::DeleteDesignBlock( const TOOL_EVENT& aEvent ) if( !current ) return -1; - getDesignBlockPane()->DeleteDesignBlockFromLibrary( current->m_LibId, true ); + if( getDesignBlockPane()->DeleteDesignBlockFromLibrary( current->m_LibId, true ) ) + { + notifyOtherFrames(); + return 0; + } - return 0; + return -1; } @@ -139,7 +155,10 @@ int DESIGN_BLOCK_CONTROL::EditDesignBlockProperties( const TOOL_EVENT& aEvent ) return -1; if( getDesignBlockPane()->EditDesignBlockProperties( current->m_LibId ) ) + { + notifyOtherFrames(); return 0; + } return -1; } @@ -190,3 +209,12 @@ LIB_TREE_NODE* DESIGN_BLOCK_CONTROL::getCurrentTreeNode() LIB_TREE* libTree = getDesignBlockPane()->GetDesignBlockPanel()->GetLibTree(); return libTree ? libTree->GetCurrentTreeNode() : nullptr; } + + +void DESIGN_BLOCK_CONTROL::notifyOtherFrames() +{ + std::string payload = ""; + + for( FRAME_T frame : m_framesToNotify ) + m_frame->Kiway().ExpressMail( frame, MAIL_RELOAD_LIB, payload ); +} diff --git a/common/tool/design_block_control.h b/common/tool/design_block_control.h index 5019a76a9b..61339df080 100644 --- a/common/tool/design_block_control.h +++ b/common/tool/design_block_control.h @@ -66,6 +66,10 @@ protected: virtual DESIGN_BLOCK_PANE* getDesignBlockPane() = 0; LIB_TREE_NODE* getCurrentTreeNode(); + /// Notify other frames that the design block lib table has changed + std::vector m_framesToNotify; + void notifyOtherFrames(); + EDA_DRAW_FRAME* m_frame = nullptr; }; diff --git a/eeschema/sch_design_block_utils.cpp b/eeschema/sch_design_block_utils.cpp index fa6ba7ce8d..5d901ef561 100644 --- a/eeschema/sch_design_block_utils.cpp +++ b/eeschema/sch_design_block_utils.cpp @@ -57,14 +57,14 @@ bool checkOverwrite( wxWindow* aFrame, wxString& libname, wxString& newName ) } -void SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, +bool SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, SCH_SHEET_PATH& aSheetPath ) { // Make sure the user has selected a library to save into if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() ) { DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) ); - return; + return false; } // Just block all attempts to create design blocks with nested sheets at this point @@ -74,7 +74,7 @@ void SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, if( !sheets.empty() ) { DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) ); - return; + return false; } DESIGN_BLOCK blk; @@ -99,7 +99,16 @@ void SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk ); if( dlg.ShowModal() != wxID_OK ) - return; + return false; + + wxString libName = blk.GetLibId().GetLibNickname(); + wxString newName = blk.GetLibId().GetLibItemName(); + + if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) + && !checkOverwrite( this, libName, newName ) ) + { + return false; + } // Save a temporary copy of the schematic file, as the plugin is just going to move it wxString tempFile = wxFileName::CreateTempFileName( "design_block" ); @@ -107,21 +116,16 @@ void SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, { DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) ); wxRemoveFile( tempFile ); - return; + return false; } blk.SetSchematicFile( tempFile ); + bool success = false; try { - wxString libName = blk.GetLibId().GetLibNickname(); - wxString newName = blk.GetLibId().GetLibItemName(); - - if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) ) - if( !checkOverwrite( this, libName, newName ) ) - return; - - Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ); + success = Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ) + == DESIGN_BLOCK_LIB_TABLE::SAVE_OK; } catch( const IO_ERROR& ioe ) { @@ -133,25 +137,27 @@ void SCH_EDIT_FRAME::SaveSheetAsDesignBlock( const wxString& aLibraryName, m_designBlocksPane->RefreshLibs(); m_designBlocksPane->SelectLibId( blk.GetLibId() ); + + return success; } -void SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) +bool SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) { - // Make sure the user has selected a library to save into - if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() ) - { - DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) ); - return; - } - // Get all selected items EE_SELECTION selection = m_toolManager->GetTool()->GetSelection(); if( selection.Empty() ) { DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) ); - return; + return false; + } + + // Make sure the user has selected a library to save into + if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() ) + { + DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) ); + return false; } // Just block all attempts to create design blocks with nested sheets at this point @@ -168,7 +174,7 @@ void SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) else DisplayErrorMessage( this, _( "Design blocks with nested sheets are not supported." ) ); - return; + return false; } DESIGN_BLOCK blk; @@ -179,7 +185,16 @@ void SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk ); if( dlg.ShowModal() != wxID_OK ) - return; + return false; + + wxString libName = blk.GetLibId().GetLibNickname(); + wxString newName = blk.GetLibId().GetLibItemName(); + + if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) + && !checkOverwrite( this, libName, newName ) ) + { + return false; + } // Create a temporary screen SCH_SCREEN* tempScreen = new SCH_SCREEN( m_schematic ); @@ -201,21 +216,16 @@ void SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) { DisplayErrorMessage( this, _( "Error saving temporary schematic file to create design block." ) ); wxRemoveFile( tempFile ); - return; + return false; } blk.SetSchematicFile( tempFile ); + bool success = false; try { - wxString libName = blk.GetLibId().GetLibNickname(); - wxString newName = blk.GetLibId().GetLibItemName(); - - if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) ) - if( !checkOverwrite( this, libName, newName ) ) - return; - - Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ); + success = Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ) + == DESIGN_BLOCK_LIB_TABLE::SAVE_OK; } catch( const IO_ERROR& ioe ) { @@ -229,4 +239,6 @@ void SCH_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) m_designBlocksPane->RefreshLibs(); m_designBlocksPane->SelectLibId( blk.GetLibId() ); + + return success; } diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index be0cde2b95..a03d43baf7 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -744,9 +744,9 @@ public: */ bool CreateArchiveLibrary( const wxString& aFileName ); - void SaveSheetAsDesignBlock( const wxString& aLibraryName, SCH_SHEET_PATH& aSheetPath ); + bool SaveSheetAsDesignBlock( const wxString& aLibraryName, SCH_SHEET_PATH& aSheetPath ); - void SaveSelectionAsDesignBlock( const wxString& aLibraryName ); + bool SaveSelectionAsDesignBlock( const wxString& aLibraryName ); SCH_DESIGN_BLOCK_PANE* GetDesignBlockPane() const { return m_designBlocksPane; } diff --git a/eeschema/tools/sch_design_block_control.cpp b/eeschema/tools/sch_design_block_control.cpp index 8b3ddd1638..c84e1c7202 100644 --- a/eeschema/tools/sch_design_block_control.cpp +++ b/eeschema/tools/sch_design_block_control.cpp @@ -39,6 +39,7 @@ bool SCH_DESIGN_BLOCK_CONTROL::Init() { m_editFrame = getEditFrame(); m_frame = m_editFrame; + m_framesToNotify = { FRAME_PCB_EDITOR }; auto isInLibrary = [this](const SELECTION& aSel ) @@ -75,8 +76,11 @@ int SCH_DESIGN_BLOCK_CONTROL::SaveSheetAsDesignBlock( const TOOL_EVENT& aEvent ) if( !current ) return -1; - m_editFrame->SaveSheetAsDesignBlock( current->m_LibId.GetLibNickname(), - m_editFrame->GetCurrentSheet() ); + if( !m_editFrame->SaveSheetAsDesignBlock( current->m_LibId.GetLibNickname(), + m_editFrame->GetCurrentSheet() ) ) + return -1; + + notifyOtherFrames(); return 0; } @@ -89,7 +93,10 @@ int SCH_DESIGN_BLOCK_CONTROL::SaveSelectionAsDesignBlock( const TOOL_EVENT& aEve if( !current ) return -1; - m_editFrame->SaveSelectionAsDesignBlock( current->m_LibId.GetLibNickname() ); + if( !m_editFrame->SaveSelectionAsDesignBlock( current->m_LibId.GetLibNickname() ) ) + return -1; + + notifyOtherFrames(); return 0; } diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index f31f1b881c..b94ea40146 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include /* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER @@ -718,6 +719,10 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) GetToolManager()->RunAction( ACTIONS::pluginsReload ); break; + case MAIL_RELOAD_LIB: + m_designBlocksPane->RefreshLibs(); + break; + // many many others. default: ; diff --git a/pcbnew/pcb_design_block_utils.cpp b/pcbnew/pcb_design_block_utils.cpp index 8e5e92867c..740ad62534 100644 --- a/pcbnew/pcb_design_block_utils.cpp +++ b/pcbnew/pcb_design_block_utils.cpp @@ -104,13 +104,13 @@ bool PCB_EDIT_FRAME::saveBoardAsFile( BOARD* aBoard, const wxString& aFileName, } -void PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName ) +bool PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName ) { // Make sure the user has selected a library to save into if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() ) { DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) ); - return; + return false; } DESIGN_BLOCK blk; @@ -121,7 +121,16 @@ void PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName ) DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk ); if( dlg.ShowModal() != wxID_OK ) - return; + return false; + + wxString libName = blk.GetLibId().GetLibNickname(); + wxString newName = blk.GetLibId().GetLibItemName(); + + if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) + && !checkOverwrite( this, libName, newName ) ) + { + return false; + } // Save a temporary copy of the schematic file, as the plugin is just going to move it wxString tempFile = wxFileName::CreateTempFileName( "design_block" ); @@ -131,21 +140,17 @@ void PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName ) DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) ); wxRemoveFile( tempFile ); - return; + return false; } blk.SetBoardFile( tempFile ); + bool success = false; + try { - wxString libName = blk.GetLibId().GetLibNickname(); - wxString newName = blk.GetLibId().GetLibItemName(); - - if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) ) - if( !checkOverwrite( this, libName, newName ) ) - return; - - Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ); + success = Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ) + == DESIGN_BLOCK_LIB_TABLE::SAVE_OK; } catch( const IO_ERROR& ioe ) { @@ -157,16 +162,18 @@ void PCB_EDIT_FRAME::SaveBoardAsDesignBlock( const wxString& aLibraryName ) m_designBlocksPane->RefreshLibs(); m_designBlocksPane->SelectLibId( blk.GetLibId() ); + + return success; } -void PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) +bool PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) { // Make sure the user has selected a library to save into if( m_designBlocksPane->GetSelectedLibId().GetLibNickname().empty() ) { DisplayErrorMessage( this, _( "Please select a library to save the design block to." ) ); - return; + return false; } // Get all selected items @@ -175,7 +182,7 @@ void PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) if( selection.Empty() ) { DisplayErrorMessage( this, _( "Please select some items to save as a design block." ) ); - return; + return false; } DESIGN_BLOCK blk; @@ -186,7 +193,16 @@ void PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) DIALOG_DESIGN_BLOCK_PROPERTIES dlg( this, &blk ); if( dlg.ShowModal() != wxID_OK ) - return; + return false; + + wxString libName = blk.GetLibId().GetLibNickname(); + wxString newName = blk.GetLibId().GetLibItemName(); + + if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) + && !checkOverwrite( this, libName, newName ) ) + { + return false; + } // Create a temporary board BOARD* tempBoard = new BOARD(); @@ -220,21 +236,17 @@ void PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) DisplayErrorMessage( this, _( "Error saving temporary board file to create design block." ) ); wxRemoveFile( tempFile ); - return; + return false; } blk.SetBoardFile( tempFile ); + bool success = false; + try { - wxString libName = blk.GetLibId().GetLibNickname(); - wxString newName = blk.GetLibId().GetLibItemName(); - - if( Prj().DesignBlockLibs()->DesignBlockExists( libName, newName ) ) - if( !checkOverwrite( this, libName, newName ) ) - return; - - Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ); + success = Prj().DesignBlockLibs()->DesignBlockSave( aLibraryName, &blk ) + == DESIGN_BLOCK_LIB_TABLE::SAVE_OK; } catch( const IO_ERROR& ioe ) { @@ -246,4 +258,6 @@ void PCB_EDIT_FRAME::SaveSelectionAsDesignBlock( const wxString& aLibraryName ) m_designBlocksPane->RefreshLibs(); m_designBlocksPane->SelectLibId( blk.GetLibId() ); + + return success; } diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 87f434d6e0..5b4c708b81 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -464,9 +464,9 @@ public: */ void RecreateCmpFileFromBoard( wxCommandEvent& aEvent ); - void SaveBoardAsDesignBlock( const wxString& aLibraryName ); + bool SaveBoardAsDesignBlock( const wxString& aLibraryName ); - void SaveSelectionAsDesignBlock( const wxString& aLibraryName ); + bool SaveSelectionAsDesignBlock( const wxString& aLibraryName ); PCB_DESIGN_BLOCK_PANE* GetDesignBlockPane() const { return m_designBlocksPane; } diff --git a/pcbnew/tools/pcb_design_block_control.cpp b/pcbnew/tools/pcb_design_block_control.cpp index aa75507314..222204e8a5 100644 --- a/pcbnew/tools/pcb_design_block_control.cpp +++ b/pcbnew/tools/pcb_design_block_control.cpp @@ -39,6 +39,7 @@ bool PCB_DESIGN_BLOCK_CONTROL::Init() { m_editFrame = getEditFrame(); m_frame = m_editFrame; + m_framesToNotify = { FRAME_SCH }; auto isInLibrary = [this](const SELECTION& aSel ) @@ -75,7 +76,10 @@ int PCB_DESIGN_BLOCK_CONTROL::SaveBoardAsDesignBlock( const TOOL_EVENT& aEvent ) if( !current ) return -1; - m_editFrame->SaveBoardAsDesignBlock( current->m_LibId.GetLibNickname() ); + if( !m_editFrame->SaveBoardAsDesignBlock( current->m_LibId.GetLibNickname() ) ) + return -1; + + notifyOtherFrames(); return 0; } @@ -88,7 +92,10 @@ int PCB_DESIGN_BLOCK_CONTROL::SaveSelectionAsDesignBlock( const TOOL_EVENT& aEve if( !current ) return -1; - m_editFrame->SaveSelectionAsDesignBlock( current->m_LibId.GetLibNickname() ); + if( !m_editFrame->SaveSelectionAsDesignBlock( current->m_LibId.GetLibNickname() ) ) + return -1; + + notifyOtherFrames(); return 0; }