ADDED Duplicate Footprint, Rename Symbol and Rename Footprint.

This commit is contained in:
Jeff Young 2022-04-21 11:57:15 +01:00
parent b42365190e
commit c6f83b6dec
19 changed files with 369 additions and 51 deletions

View File

@ -189,11 +189,12 @@ LIB_TREE_NODE_UNIT& LIB_TREE_NODE_LIB_ID::AddUnit( LIB_TREE_ITEM* aItem, int aUn
void LIB_TREE_NODE_LIB_ID::Update( LIB_TREE_ITEM* aItem )
{
// Update is called when the names match, so just update the other fields.
m_LibId.SetLibNickname( aItem->GetLibId().GetLibNickname() );
m_LibId.SetLibItemName( aItem->GetName() );
m_Name = aItem->GetName();
m_Desc = aItem->GetDescription();
m_MatchName = aItem->GetName();
m_SearchText = aItem->GetSearchText();
m_Normalized = false;

View File

@ -317,7 +317,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
{
wxString msg;
msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
UnescapeString( newName ),
libName );
DisplayErrorMessage( this, msg );

View File

@ -1014,6 +1014,23 @@ void SYMBOL_EDIT_FRAME::RefreshLibraryTree()
}
void SYMBOL_EDIT_FRAME::FocusOnLibId( const LIB_ID& aLibID )
{
m_treePane->GetLibTree()->SelectLibId( aLibID );
}
void SYMBOL_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol )
{
if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
// from file therefore not yet in tree.
{
static_cast<LIB_TREE_NODE_LIB_ID*>( aTreeItem.GetID() )->Update( aSymbol );
m_treePane->GetLibTree()->RefreshLibTree();
}
}
SYMBOL_LIB_TABLE* SYMBOL_EDIT_FRAME::selectSymLibTable( bool aOptional )
{
// If no project is loaded, always work with the global table
@ -1087,11 +1104,11 @@ void SYMBOL_EDIT_FRAME::storeCurrentSymbol()
}
bool SYMBOL_EDIT_FRAME::isCurrentSymbol( const LIB_ID& aLibId ) const
bool SYMBOL_EDIT_FRAME::IsCurrentSymbol( const LIB_ID& aLibId ) const
{
// This will return the root symbol of any alias
LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(),
aLibId.GetLibNickname() );
aLibId.GetLibNickname() );
// Now we can compare the libId of the current symbol and the root symbol
return ( symbol && m_symbol && symbol->GetLibId() == m_symbol->GetLibId() );

View File

@ -312,6 +312,19 @@ public:
*/
void RefreshLibraryTree();
/**
* Update a symbol node in the library tree.
*/
void UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol );
/**
* Return either the symbol selected in the symbol tree (if context menu is active) or the
* symbol on the editor canvas.
*/
LIB_ID GetTargetLibId() const;
void FocusOnLibId( const LIB_ID& aLibID );
/**
* Called after the preferences dialog is run.
*/
@ -356,13 +369,12 @@ public:
bool IsSymbolAlias() const;
///< Return true if \a aLibId is an alias for the editor screen symbol.
bool IsCurrentSymbol( const LIB_ID& aLibId ) const;
///< Restore the empty editor screen, without any symbol or library selected.
void emptyScreen();
///< Return either the symbol selected in the symbol tree, if context menu is active or the
///< currently modified symbol.
LIB_ID GetTargetLibId() const;
protected:
void setupUIConditions() override;
@ -469,9 +481,6 @@ private:
///< Store the currently modified symbol in the library manager buffer.
void storeCurrentSymbol();
///< Return true if \a aLibId is an alias for the editor screen symbol.
bool isCurrentSymbol( const LIB_ID& aLibId ) const;
///< Rename LIB_SYMBOL aliases to avoid conflicts before adding a symbol to a library.
void ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary );

View File

@ -868,7 +868,7 @@ void SYMBOL_EDIT_FRAME::DeleteSymbolFromLibrary()
return;
}
if( isCurrentSymbol( libId ) )
if( IsCurrentSymbol( libId ) )
emptyScreen();
m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
@ -1027,7 +1027,7 @@ void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
}
else
{
reload_currentSymbol = isCurrentSymbol( libId );
reload_currentSymbol = IsCurrentSymbol( libId );
}
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -284,11 +284,25 @@ bool SYMBOL_LIBRARY_MANAGER::IsSymbolModified( const wxString& aAlias,
return false;
const LIB_BUFFER& buf = libIt->second;
auto symbolBuf = buf.GetBuffer( aAlias );
const std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
return symbolBuf ? symbolBuf->IsModified() : false;
}
void SYMBOL_LIBRARY_MANAGER::SetSymbolModified( const wxString& aAlias,
const wxString& aLibrary )
{
auto libIt = m_libs.find( aLibrary );
if( libIt == m_libs.end() )
return;
const LIB_BUFFER& buf = libIt->second;
std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
symbolBuf->GetScreen()->SetContentModified();
}
bool SYMBOL_LIBRARY_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
{
auto libIt = m_libs.find( aLibrary );

View File

@ -2,7 +2,7 @@
* This program source code file is symbol of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -175,6 +175,8 @@ public:
*/
bool IsSymbolModified( const wxString& aAlias, const wxString& aLibrary ) const;
void SetSymbolModified( const wxString& aAlias, const wxString& aLibrary );
/**
* Clear the modified flag for all symbols in a library.
*/

View File

@ -133,6 +133,11 @@ TOOL_ACTION EE_ACTIONS::duplicateSymbol( "eeschema.SymbolLibraryControl.duplicat
_( "Duplicate Symbol" ), _( "Make a copy of the selected symbol" ),
BITMAPS::duplicate );
TOOL_ACTION EE_ACTIONS::renameSymbol( "eeschema.SymbolLibraryControl.renameFootprint",
AS_GLOBAL, 0, "",
_( "Rename Symbol..." ), _( "Rename the selected symbol" ),
BITMAPS::edit );
TOOL_ACTION EE_ACTIONS::saveSymbolAs( "eeschema.SymbolLibraryControl.saveSymbolAs",
AS_GLOBAL, 0, "",
_( "Save As..." ), _( "Save the current symbol to a different library." ),

View File

@ -179,6 +179,7 @@ public:
static TOOL_ACTION newSymbol;
static TOOL_ACTION editSymbol;
static TOOL_ACTION duplicateSymbol;
static TOOL_ACTION renameSymbol;
static TOOL_ACTION deleteSymbol;
static TOOL_ACTION cutSymbol;
static TOOL_ACTION copySymbol;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -36,7 +36,8 @@
#include <bitmaps/bitmap_types.h>
#include <confirm.h>
#include <wx/filedlg.h>
#include "wx/generic/textdlgg.h"
#include "string_utils.h"
bool SYMBOL_EDITOR_CONTROL::Init()
{
@ -108,6 +109,7 @@ bool SYMBOL_EDITOR_CONTROL::Init()
ctxMenu.AddItem( EE_ACTIONS::copySymbol, symbolSelectedCondition );
ctxMenu.AddItem( EE_ACTIONS::pasteSymbol, libInferredCondition );
ctxMenu.AddItem( EE_ACTIONS::duplicateSymbol, symbolSelectedCondition );
ctxMenu.AddItem( EE_ACTIONS::renameSymbol, symbolSelectedCondition );
ctxMenu.AddItem( EE_ACTIONS::deleteSymbol, symbolSelectedCondition );
ctxMenu.AddSeparator();
@ -285,6 +287,96 @@ int SYMBOL_EDITOR_CONTROL::DuplicateSymbol( const TOOL_EVENT& aEvent )
}
int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent )
{
if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
{
SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
LIB_ID libId = editFrame->GetTreeLIBID();
wxString libName = libId.GetLibNickname();
wxString symbolName = libId.GetLibItemName();
wxString newName = symbolName;
bool done = false;
if( !libMgr.LibraryExists( libName ) )
return 0;
while( !done )
{
wxTextEntryDialog dlg( m_frame, _( "New name:" ), _( "Change Symbol Name" ), newName );
if( dlg.ShowModal() != wxID_OK )
return 0; // canceled by user
newName = dlg.GetValue();
newName.Trim( true ).Trim( false );
if( newName.IsEmpty() )
{
DisplayErrorMessage( editFrame, _( "Symbol name cannot be empty." ) );
}
else if( libMgr.SymbolExists( newName, libName ) )
{
DisplayErrorMessage( editFrame, wxString::Format( _( "Symbol name '%s' already "
"in use in library '%s'." ),
UnescapeString( newName ),
libName ) );
newName = symbolName;
}
else
{
done = true;
}
}
wxString oldName = symbolName;
LIB_SYMBOL* libSymbol = nullptr;
if( editFrame->IsCurrentSymbol( libId ) )
{
// Update buffered copy
libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
libSymbol->SetName( newName );
libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
// Now update canvasy copy
libSymbol = editFrame->GetCurSymbol();
libSymbol->SetName( newName );
libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
editFrame->RebuildView();
editFrame->OnModify();
// N.B. The view needs to be rebuilt first as the Symbol Properties change may
// invalidate the view pointers by rebuilting the field table
editFrame->UpdateMsgPanel();
}
else
{
libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
libSymbol->SetName( newName );
libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
libMgr.SetSymbolModified( newName, libName );
}
wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( libId );
editFrame->UpdateLibraryTree( treeItem, libSymbol );
editFrame->FocusOnLibId( LIB_ID( libName, newName ) );
}
return 0;
}
int SYMBOL_EDITOR_CONTROL::OnDeMorgan( const TOOL_EVENT& aEvent )
{
int convert = aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard ) ?
@ -453,9 +545,8 @@ int SYMBOL_EDITOR_CONTROL::ExportSymbolAsSVG( const TOOL_EVENT& aEvent )
PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
PAGE_INFO pageTemp = pageSave;
VECTOR2I symbolSize =
symbol->GetUnitBoundingBox( editFrame->GetUnit(),
editFrame->GetConvert() ).GetSize();
VECTOR2I symbolSize = symbol->GetUnitBoundingBox( editFrame->GetUnit(),
editFrame->GetConvert() ).GetSize();
// Add a small margin to the plot bounding box
pageTemp.SetWidthMils( int( symbolSize.x * 1.2 ) );
@ -552,6 +643,7 @@ void SYMBOL_EDITOR_CONTROL::setTransitions()
Go( &SYMBOL_EDITOR_CONTROL::Revert, ACTIONS::revert.MakeEvent() );
Go( &SYMBOL_EDITOR_CONTROL::DuplicateSymbol, EE_ACTIONS::duplicateSymbol.MakeEvent() );
Go( &SYMBOL_EDITOR_CONTROL::RenameSymbol, EE_ACTIONS::renameSymbol.MakeEvent() );
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::deleteSymbol.MakeEvent() );
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::cutSymbol.MakeEvent() );
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::copySymbol.MakeEvent() );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -55,6 +55,7 @@ public:
int CutCopyDelete( const TOOL_EVENT& aEvent );
int DuplicateSymbol( const TOOL_EVENT& aEvent );
int RenameSymbol( const TOOL_EVENT& aEvent );
int ExportSymbol( const TOOL_EVENT& aEvent );
int ExportView( const TOOL_EVENT& aEvent );
int ExportSymbolAsSVG( const TOOL_EVENT& aEvent );

View File

@ -181,6 +181,7 @@ public:
* @return : true if OK, false if abort
*/
bool SaveFootprint( FOOTPRINT* aFootprint );
bool DuplicateFootprint( FOOTPRINT* aFootprint );
bool SaveFootprintAs( FOOTPRINT* aFootprint );
bool SaveFootprintToBoard( bool aAddNew );
bool SaveFootprintInLibrary( FOOTPRINT* aFootprint, const wxString& aLibraryName );
@ -306,6 +307,11 @@ public:
*/
void RefreshLibraryTree();
/**
* Update a single node in the library tree.
*/
void UpdateLibraryTree( const wxDataViewItem& treeItem, FOOTPRINT* aFootprint );
///< Reload displayed items and sets view.
void UpdateView();

View File

@ -148,6 +148,20 @@ public:
};
void FOOTPRINT_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem,
FOOTPRINT* aFootprint )
{
BASIC_FOOTPRINT_INFO footprintInfo( aFootprint );
if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
// from file therefore not yet in tree.
{
static_cast<LIB_TREE_NODE_LIB_ID*>( aTreeItem.GetID() )->Update( &footprintInfo );
m_treePane->GetLibTree()->RefreshLibTree();
}
}
void FOOTPRINT_EDIT_FRAME::editFootprintProperties( FOOTPRINT* aFootprint )
{
LIB_ID oldFPID = aFootprint->GetFPID();
@ -155,18 +169,10 @@ void FOOTPRINT_EDIT_FRAME::editFootprintProperties( FOOTPRINT* aFootprint )
DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( this, aFootprint );
dialog.ShowModal();
// Update library tree
BASIC_FOOTPRINT_INFO footprintInfo( aFootprint );
wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
if( treeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
// from file therefore not yet in tree.
{
static_cast<LIB_TREE_NODE_LIB_ID*>( treeItem.GetID() )->Update( &footprintInfo );
m_treePane->GetLibTree()->RefreshLibTree();
}
UpdateTitle(); // in case of a name change...
// Update library tree and title in case of a name change
wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
UpdateLibraryTree( treeItem, aFootprint );
UpdateTitle();
UpdateMsgPanel();
}

View File

@ -851,6 +851,39 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( FOOTPRINT* aFootprint )
}
bool FOOTPRINT_EDIT_FRAME::DuplicateFootprint( FOOTPRINT* aFootprint )
{
LIB_ID fpID = aFootprint->GetFPID();
wxString libraryName = fpID.GetLibNickname();
wxString footprintName = fpID.GetLibItemName();
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to add/replace a footprint in a legacy lib
wxString libFullName = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
if( IO_MGR::GuessPluginTypeFromLibPath( libFullName ) == IO_MGR::LEGACY )
{
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
return false;
}
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
int i = 1;
wxString newName = footprintName;
// Append a number to the name until the name is unique in the library.
while( tbl->FootprintExists( libraryName, newName ) )
newName.Printf( "%s_%d", footprintName, i++ );
aFootprint->SetFPID( LIB_ID( libraryName, newName ) );
if( aFootprint->GetValue() == footprintName )
aFootprint->SetValue( newName );
return SaveFootprintInLibrary( aFootprint, libraryName );
}
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( FOOTPRINT* aFootprint,
const wxString& aLibraryName )
{

View File

@ -177,7 +177,8 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
case 0:
if( node->m_LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
{
node->m_Name = m_frame->GetLoadedFPID().GetLibItemName();
// Do not use GetLoadedFPID(); it returns m_footprintNameWhenLoaded.
node->m_Name = m_frame->GetBoard()->GetFirstFootprint()->GetFPID().GetLibItemName();
// mark modified part with an asterisk
if( m_frame->GetScreen()->IsContentModified() )

View File

@ -25,6 +25,8 @@
#include "footprint_editor_control.h"
#include "kicad_clipboard.h"
#include "wx/generic/textdlgg.h"
#include "string_utils.h"
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <view/view_controls.h>
@ -109,31 +111,33 @@ bool FOOTPRINT_EDITOR_CONTROL::Init()
return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
};
ctxMenu.AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition );
ctxMenu.AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition );
ctxMenu.AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition );
ctxMenu.AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition );
ctxMenu.AddSeparator();
ctxMenu.AddItem( PCB_ACTIONS::newFootprint, libSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::createFootprint, libSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::newFootprint, libSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::createFootprint, libSelectedCondition );
ctxMenu.AddSeparator();
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition || libInferredCondition );
ctxMenu.AddItem( ACTIONS::saveAs, libSelectedCondition );
ctxMenu.AddItem( ACTIONS::saveCopyAs, fpSelectedCondition );
ctxMenu.AddItem( ACTIONS::revert, libSelectedCondition || libInferredCondition );
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition || libInferredCondition );
ctxMenu.AddItem( ACTIONS::saveAs, libSelectedCondition );
ctxMenu.AddItem( ACTIONS::saveCopyAs, fpSelectedCondition );
ctxMenu.AddItem( ACTIONS::revert, libSelectedCondition || libInferredCondition );
ctxMenu.AddSeparator();
ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::pasteFootprint, libInferredCondition );
ctxMenu.AddItem( PCB_ACTIONS::deleteFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::pasteFootprint, libInferredCondition );
ctxMenu.AddItem( PCB_ACTIONS::duplicateFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::renameFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::deleteFootprint, fpSelectedCondition );
ctxMenu.AddSeparator();
ctxMenu.AddItem( PCB_ACTIONS::importFootprint, libInferredCondition );
ctxMenu.AddItem( PCB_ACTIONS::exportFootprint, fpSelectedCondition );
ctxMenu.AddItem( PCB_ACTIONS::importFootprint, libInferredCondition );
ctxMenu.AddItem( PCB_ACTIONS::exportFootprint, fpSelectedCondition );
// If we've got nothing else to show, at least show a hide tree option
ctxMenu.AddItem( PCB_ACTIONS::hideFootprintTree, !libInferredCondition );
ctxMenu.AddItem( PCB_ACTIONS::hideFootprintTree, !libInferredCondition );
return true;
}
@ -357,6 +361,116 @@ int FOOTPRINT_EDITOR_CONTROL::PasteFootprint( const TOOL_EVENT& aEvent )
}
int FOOTPRINT_EDITOR_CONTROL::DuplicateFootprint( const TOOL_EVENT& aEvent )
{
LIB_ID fpID = m_frame->GetTreeFPID();
wxString libraryName = fpID.GetLibNickname();
wxString footprintName = fpID.GetLibItemName();
FOOTPRINT* footprint;
if( fpID == m_frame->GetLoadedFPID() )
footprint = new FOOTPRINT( *m_frame->GetBoard()->GetFirstFootprint() );
else
footprint = m_frame->LoadFootprint( m_frame->GetTargetFPID() );
if( footprint && m_frame->DuplicateFootprint( footprint ) )
{
m_frame->SyncLibraryTree( true );
m_frame->FocusOnLibID( footprint->GetFPID() );
m_frame->RefreshLibraryTree();
}
return 0;
}
int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
{
FP_LIB_TABLE* tbl = m_frame->Prj().PcbFootprintLibs();
LIB_ID fpID = m_frame->GetTreeFPID();
wxString libraryName = fpID.GetLibNickname();
wxString oldName = fpID.GetLibItemName();
wxString newName = oldName;
bool done = false;
while( !done )
{
wxTextEntryDialog dlg( m_frame, _( "New name:" ), _( "Change Footprint Name" ), newName );
if( dlg.ShowModal() != wxID_OK )
return 0; // canceled by user
newName = dlg.GetValue();
newName.Trim( true ).Trim( false );
if( newName.IsEmpty() )
{
DisplayErrorMessage( m_frame, _( "Footprint name cannot be empty." ) );
}
else if( tbl->FootprintExists( libraryName, newName ) )
{
DisplayErrorMessage( m_frame, wxString::Format( _( "Footprint name '%s' already "
"in use in library '%s'." ),
UnescapeString( newName ),
libraryName ) );
newName = oldName;
}
else
{
done = true;
}
}
FOOTPRINT* footprint = nullptr;
if( fpID == m_frame->GetLoadedFPID() )
{
footprint = m_frame->GetBoard()->GetFirstFootprint();
if( footprint )
{
footprint->SetFPID( LIB_ID( libraryName, newName ) );
if( footprint->GetValue() == oldName )
footprint->SetValue( newName );
m_frame->OnModify();
m_frame->UpdateView();
}
}
else
{
footprint = m_frame->LoadFootprint( fpID );
try
{
footprint->SetFPID( LIB_ID( libraryName, newName ) );
if( footprint->GetValue() == oldName )
footprint->SetValue( newName );
m_frame->SaveFootprintInLibrary( footprint, libraryName );
m_frame->Prj().PcbFootprintLibs()->FootprintDelete( libraryName, oldName );
}
catch( const IO_ERROR& ioe )
{
DisplayError( m_frame, ioe.What() );
}
catch( ... )
{
// Best efforts...
}
}
wxDataViewItem treeItem = m_frame->GetLibTreeAdapter()->FindItem( fpID );
m_frame->UpdateLibraryTree( treeItem, footprint );
m_frame->FocusOnLibID( LIB_ID( libraryName, newName ) );
return 0;
}
int FOOTPRINT_EDITOR_CONTROL::DeleteFootprint( const TOOL_EVENT& aEvent )
{
FOOTPRINT_EDIT_FRAME* frame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
@ -608,6 +722,8 @@ void FOOTPRINT_EDITOR_CONTROL::setTransitions()
Go( &FOOTPRINT_EDITOR_CONTROL::SaveAs, ACTIONS::saveAs.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::SaveAs, ACTIONS::saveCopyAs.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::Revert, ACTIONS::revert.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::DuplicateFootprint, PCB_ACTIONS::duplicateFootprint.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::RenameFootprint, PCB_ACTIONS::renameFootprint.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::DeleteFootprint, PCB_ACTIONS::deleteFootprint.MakeEvent() );
Go( &FOOTPRINT_EDITOR_CONTROL::EditFootprint, PCB_ACTIONS::editFootprint.MakeEvent() );

View File

@ -58,6 +58,8 @@ public:
int EditFootprint( const TOOL_EVENT& aEvent );
int CutCopyFootprint( const TOOL_EVENT& aEvent );
int PasteFootprint( const TOOL_EVENT& aEvent );
int DuplicateFootprint( const TOOL_EVENT& aEvent );
int RenameFootprint( const TOOL_EVENT& aEvent );
int DeleteFootprint( const TOOL_EVENT& aEvent );
int ImportFootprint( const TOOL_EVENT& aEvent );
int ExportFootprint( const TOOL_EVENT& aEvent );

View File

@ -369,6 +369,16 @@ TOOL_ACTION PCB_ACTIONS::editFootprint( "pcbnew.ModuleEditor.editFootprint",
_( "Edit Footprint" ), _( "Show selected footprint on editor canvas" ),
BITMAPS::edit );
TOOL_ACTION PCB_ACTIONS::duplicateFootprint( "pcbnew.ModuleEditor.duplicateFootprint",
AS_GLOBAL, 0, "",
_( "Duplicate Footprint" ), _( "Make a copy of the selected footprint" ),
BITMAPS::duplicate );
TOOL_ACTION PCB_ACTIONS::renameFootprint( "pcbnew.ModuleEditor.renameFootprint",
AS_GLOBAL, 0, "",
_( "Rename Footprint..." ), _( "Rename the selected footprint" ),
BITMAPS::edit );
TOOL_ACTION PCB_ACTIONS::deleteFootprint( "pcbnew.ModuleEditor.deleteFootprint",
AS_GLOBAL, 0, "",
_( "Delete Footprint from Library" ), _( "Delete Footprint from Library" ),

View File

@ -374,6 +374,8 @@ public:
static TOOL_ACTION saveToLibrary;
static TOOL_ACTION editFootprint;
static TOOL_ACTION duplicateFootprint;
static TOOL_ACTION renameFootprint;
static TOOL_ACTION deleteFootprint;
static TOOL_ACTION cutFootprint;
static TOOL_ACTION copyFootprint;