7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-18 19:09:17 +00:00

design blocks: cross-editor notification of library actions

This commit is contained in:
Mike Williams 2025-02-05 12:20:17 -05:00
parent 97aa507dd4
commit 9389a2b7c5
11 changed files with 166 additions and 78 deletions

View File

@ -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<std::string, UTF8>* 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<std::string, UTF8>* aProperties )

View File

@ -76,10 +76,7 @@ public:
}
bool DesignBlockExists( const wxString& aLibraryPath, const wxString& aDesignBlockName,
const std::map<std::string, UTF8>* aProperties = nullptr )
{
return DesignBlockLoad( aLibraryPath, aDesignBlockName, true, aProperties ) != nullptr;
}
const std::map<std::string, UTF8>* aProperties = nullptr );
DESIGN_BLOCK* ImportDesignBlock( const wxString& aDesignBlockPath,
wxString& aDesignBlockNameOut,

View File

@ -26,6 +26,8 @@
#include <widgets/design_block_pane.h>
#include <widgets/panel_design_block_chooser.h>
#include <dialog_design_block_properties.h>
#include <mail_type.h>
#include <kiway.h>
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 );
}

View File

@ -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<FRAME_T> m_framesToNotify;
void notifyOtherFrames();
EDA_DRAW_FRAME* m_frame = nullptr;
};

View File

@ -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<EE_SELECTION_TOOL>()->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;
}

View File

@ -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; }

View File

@ -39,6 +39,7 @@ bool SCH_DESIGN_BLOCK_CONTROL::Init()
{
m_editFrame = getEditFrame<SCH_EDIT_FRAME>();
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;
}

View File

@ -54,6 +54,7 @@
#include <tools/pcb_actions.h>
#include <tools/pcb_selection_tool.h>
#include <netlist_reader/netlist_reader.h>
#include <widgets/pcb_design_block_pane.h>
#include <wx/log.h>
/* 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:
;

View File

@ -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;
}

View File

@ -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; }

View File

@ -39,6 +39,7 @@ bool PCB_DESIGN_BLOCK_CONTROL::Init()
{
m_editFrame = getEditFrame<PCB_EDIT_FRAME>();
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;
}