ADDED Duplicate Footprint, Rename Symbol and Rename Footprint.
This commit is contained in:
parent
b42365190e
commit
c6f83b6dec
|
@ -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 )
|
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.SetLibNickname( aItem->GetLibId().GetLibNickname() );
|
||||||
|
m_LibId.SetLibItemName( aItem->GetName() );
|
||||||
|
|
||||||
|
m_Name = aItem->GetName();
|
||||||
m_Desc = aItem->GetDescription();
|
m_Desc = aItem->GetDescription();
|
||||||
|
m_MatchName = aItem->GetName();
|
||||||
|
|
||||||
m_SearchText = aItem->GetSearchText();
|
m_SearchText = aItem->GetSearchText();
|
||||||
m_Normalized = false;
|
m_Normalized = false;
|
||||||
|
|
|
@ -317,7 +317,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||||
{
|
{
|
||||||
wxString msg;
|
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 ),
|
UnescapeString( newName ),
|
||||||
libName );
|
libName );
|
||||||
DisplayErrorMessage( this, msg );
|
DisplayErrorMessage( this, msg );
|
||||||
|
|
|
@ -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 )
|
SYMBOL_LIB_TABLE* SYMBOL_EDIT_FRAME::selectSymLibTable( bool aOptional )
|
||||||
{
|
{
|
||||||
// If no project is loaded, always work with the global table
|
// If no project is loaded, always work with the global table
|
||||||
|
@ -1087,7 +1104,7 @@ 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
|
// This will return the root symbol of any alias
|
||||||
LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(),
|
LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(),
|
||||||
|
|
|
@ -312,6 +312,19 @@ public:
|
||||||
*/
|
*/
|
||||||
void RefreshLibraryTree();
|
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.
|
* Called after the preferences dialog is run.
|
||||||
*/
|
*/
|
||||||
|
@ -356,13 +369,12 @@ public:
|
||||||
|
|
||||||
bool IsSymbolAlias() const;
|
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.
|
///< Restore the empty editor screen, without any symbol or library selected.
|
||||||
void emptyScreen();
|
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:
|
protected:
|
||||||
void setupUIConditions() override;
|
void setupUIConditions() override;
|
||||||
|
|
||||||
|
@ -469,9 +481,6 @@ private:
|
||||||
///< Store the currently modified symbol in the library manager buffer.
|
///< Store the currently modified symbol in the library manager buffer.
|
||||||
void storeCurrentSymbol();
|
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.
|
///< Rename LIB_SYMBOL aliases to avoid conflicts before adding a symbol to a library.
|
||||||
void ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary );
|
void ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary );
|
||||||
|
|
||||||
|
|
|
@ -868,7 +868,7 @@ void SYMBOL_EDIT_FRAME::DeleteSymbolFromLibrary()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isCurrentSymbol( libId ) )
|
if( IsCurrentSymbol( libId ) )
|
||||||
emptyScreen();
|
emptyScreen();
|
||||||
|
|
||||||
m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
|
m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
|
||||||
|
@ -1027,7 +1027,7 @@ void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reload_currentSymbol = isCurrentSymbol( libId );
|
reload_currentSymbol = IsCurrentSymbol( libId );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 CERN
|
* 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>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* 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;
|
return false;
|
||||||
|
|
||||||
const LIB_BUFFER& buf = libIt->second;
|
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;
|
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
|
bool SYMBOL_LIBRARY_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
|
||||||
{
|
{
|
||||||
auto libIt = m_libs.find( aLibrary );
|
auto libIt = m_libs.find( aLibrary );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is symbol of KiCad, a free EDA CAD application.
|
* This program source code file is symbol of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 CERN
|
* 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>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -175,6 +175,8 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsSymbolModified( const wxString& aAlias, const wxString& aLibrary ) const;
|
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.
|
* Clear the modified flag for all symbols in a library.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -133,6 +133,11 @@ TOOL_ACTION EE_ACTIONS::duplicateSymbol( "eeschema.SymbolLibraryControl.duplicat
|
||||||
_( "Duplicate Symbol" ), _( "Make a copy of the selected symbol" ),
|
_( "Duplicate Symbol" ), _( "Make a copy of the selected symbol" ),
|
||||||
BITMAPS::duplicate );
|
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",
|
TOOL_ACTION EE_ACTIONS::saveSymbolAs( "eeschema.SymbolLibraryControl.saveSymbolAs",
|
||||||
AS_GLOBAL, 0, "",
|
AS_GLOBAL, 0, "",
|
||||||
_( "Save As..." ), _( "Save the current symbol to a different library." ),
|
_( "Save As..." ), _( "Save the current symbol to a different library." ),
|
||||||
|
|
|
@ -179,6 +179,7 @@ public:
|
||||||
static TOOL_ACTION newSymbol;
|
static TOOL_ACTION newSymbol;
|
||||||
static TOOL_ACTION editSymbol;
|
static TOOL_ACTION editSymbol;
|
||||||
static TOOL_ACTION duplicateSymbol;
|
static TOOL_ACTION duplicateSymbol;
|
||||||
|
static TOOL_ACTION renameSymbol;
|
||||||
static TOOL_ACTION deleteSymbol;
|
static TOOL_ACTION deleteSymbol;
|
||||||
static TOOL_ACTION cutSymbol;
|
static TOOL_ACTION cutSymbol;
|
||||||
static TOOL_ACTION copySymbol;
|
static TOOL_ACTION copySymbol;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -36,7 +36,8 @@
|
||||||
#include <bitmaps/bitmap_types.h>
|
#include <bitmaps/bitmap_types.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <wx/filedlg.h>
|
#include <wx/filedlg.h>
|
||||||
|
#include "wx/generic/textdlgg.h"
|
||||||
|
#include "string_utils.h"
|
||||||
|
|
||||||
bool SYMBOL_EDITOR_CONTROL::Init()
|
bool SYMBOL_EDITOR_CONTROL::Init()
|
||||||
{
|
{
|
||||||
|
@ -108,6 +109,7 @@ bool SYMBOL_EDITOR_CONTROL::Init()
|
||||||
ctxMenu.AddItem( EE_ACTIONS::copySymbol, symbolSelectedCondition );
|
ctxMenu.AddItem( EE_ACTIONS::copySymbol, symbolSelectedCondition );
|
||||||
ctxMenu.AddItem( EE_ACTIONS::pasteSymbol, libInferredCondition );
|
ctxMenu.AddItem( EE_ACTIONS::pasteSymbol, libInferredCondition );
|
||||||
ctxMenu.AddItem( EE_ACTIONS::duplicateSymbol, symbolSelectedCondition );
|
ctxMenu.AddItem( EE_ACTIONS::duplicateSymbol, symbolSelectedCondition );
|
||||||
|
ctxMenu.AddItem( EE_ACTIONS::renameSymbol, symbolSelectedCondition );
|
||||||
ctxMenu.AddItem( EE_ACTIONS::deleteSymbol, symbolSelectedCondition );
|
ctxMenu.AddItem( EE_ACTIONS::deleteSymbol, symbolSelectedCondition );
|
||||||
|
|
||||||
ctxMenu.AddSeparator();
|
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 SYMBOL_EDITOR_CONTROL::OnDeMorgan( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
int convert = aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard ) ?
|
int convert = aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard ) ?
|
||||||
|
@ -453,8 +545,7 @@ int SYMBOL_EDITOR_CONTROL::ExportSymbolAsSVG( const TOOL_EVENT& aEvent )
|
||||||
PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
|
PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
|
||||||
PAGE_INFO pageTemp = pageSave;
|
PAGE_INFO pageTemp = pageSave;
|
||||||
|
|
||||||
VECTOR2I symbolSize =
|
VECTOR2I symbolSize = symbol->GetUnitBoundingBox( editFrame->GetUnit(),
|
||||||
symbol->GetUnitBoundingBox( editFrame->GetUnit(),
|
|
||||||
editFrame->GetConvert() ).GetSize();
|
editFrame->GetConvert() ).GetSize();
|
||||||
|
|
||||||
// Add a small margin to the plot bounding box
|
// Add a small margin to the plot bounding box
|
||||||
|
@ -552,6 +643,7 @@ void SYMBOL_EDITOR_CONTROL::setTransitions()
|
||||||
Go( &SYMBOL_EDITOR_CONTROL::Revert, ACTIONS::revert.MakeEvent() );
|
Go( &SYMBOL_EDITOR_CONTROL::Revert, ACTIONS::revert.MakeEvent() );
|
||||||
|
|
||||||
Go( &SYMBOL_EDITOR_CONTROL::DuplicateSymbol, EE_ACTIONS::duplicateSymbol.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::deleteSymbol.MakeEvent() );
|
||||||
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::cutSymbol.MakeEvent() );
|
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::cutSymbol.MakeEvent() );
|
||||||
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::copySymbol.MakeEvent() );
|
Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::copySymbol.MakeEvent() );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -55,6 +55,7 @@ public:
|
||||||
|
|
||||||
int CutCopyDelete( const TOOL_EVENT& aEvent );
|
int CutCopyDelete( const TOOL_EVENT& aEvent );
|
||||||
int DuplicateSymbol( const TOOL_EVENT& aEvent );
|
int DuplicateSymbol( const TOOL_EVENT& aEvent );
|
||||||
|
int RenameSymbol( const TOOL_EVENT& aEvent );
|
||||||
int ExportSymbol( const TOOL_EVENT& aEvent );
|
int ExportSymbol( const TOOL_EVENT& aEvent );
|
||||||
int ExportView( const TOOL_EVENT& aEvent );
|
int ExportView( const TOOL_EVENT& aEvent );
|
||||||
int ExportSymbolAsSVG( const TOOL_EVENT& aEvent );
|
int ExportSymbolAsSVG( const TOOL_EVENT& aEvent );
|
||||||
|
|
|
@ -181,6 +181,7 @@ public:
|
||||||
* @return : true if OK, false if abort
|
* @return : true if OK, false if abort
|
||||||
*/
|
*/
|
||||||
bool SaveFootprint( FOOTPRINT* aFootprint );
|
bool SaveFootprint( FOOTPRINT* aFootprint );
|
||||||
|
bool DuplicateFootprint( FOOTPRINT* aFootprint );
|
||||||
bool SaveFootprintAs( FOOTPRINT* aFootprint );
|
bool SaveFootprintAs( FOOTPRINT* aFootprint );
|
||||||
bool SaveFootprintToBoard( bool aAddNew );
|
bool SaveFootprintToBoard( bool aAddNew );
|
||||||
bool SaveFootprintInLibrary( FOOTPRINT* aFootprint, const wxString& aLibraryName );
|
bool SaveFootprintInLibrary( FOOTPRINT* aFootprint, const wxString& aLibraryName );
|
||||||
|
@ -306,6 +307,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void RefreshLibraryTree();
|
void RefreshLibraryTree();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a single node in the library tree.
|
||||||
|
*/
|
||||||
|
void UpdateLibraryTree( const wxDataViewItem& treeItem, FOOTPRINT* aFootprint );
|
||||||
|
|
||||||
///< Reload displayed items and sets view.
|
///< Reload displayed items and sets view.
|
||||||
void UpdateView();
|
void UpdateView();
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
void FOOTPRINT_EDIT_FRAME::editFootprintProperties( FOOTPRINT* aFootprint )
|
||||||
{
|
{
|
||||||
LIB_ID oldFPID = aFootprint->GetFPID();
|
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_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( this, aFootprint );
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
|
|
||||||
// Update library tree
|
// Update library tree and title in case of a name change
|
||||||
BASIC_FOOTPRINT_INFO footprintInfo( aFootprint );
|
|
||||||
wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
|
wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
|
||||||
|
UpdateLibraryTree( treeItem, aFootprint );
|
||||||
if( treeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
|
UpdateTitle();
|
||||||
// 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...
|
|
||||||
|
|
||||||
UpdateMsgPanel();
|
UpdateMsgPanel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( FOOTPRINT* aFootprint,
|
||||||
const wxString& aLibraryName )
|
const wxString& aLibraryName )
|
||||||
{
|
{
|
||||||
|
|
|
@ -177,7 +177,8 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
|
||||||
case 0:
|
case 0:
|
||||||
if( node->m_LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
|
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
|
// mark modified part with an asterisk
|
||||||
if( m_frame->GetScreen()->IsContentModified() )
|
if( m_frame->GetScreen()->IsContentModified() )
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include "footprint_editor_control.h"
|
#include "footprint_editor_control.h"
|
||||||
#include "kicad_clipboard.h"
|
#include "kicad_clipboard.h"
|
||||||
|
#include "wx/generic/textdlgg.h"
|
||||||
|
#include "string_utils.h"
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tools/pcb_actions.h>
|
#include <tools/pcb_actions.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
|
@ -126,6 +128,8 @@ bool FOOTPRINT_EDITOR_CONTROL::Init()
|
||||||
ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition );
|
ctxMenu.AddItem( PCB_ACTIONS::cutFootprint, fpSelectedCondition );
|
||||||
ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition );
|
ctxMenu.AddItem( PCB_ACTIONS::copyFootprint, fpSelectedCondition );
|
||||||
ctxMenu.AddItem( PCB_ACTIONS::pasteFootprint, libInferredCondition );
|
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.AddItem( PCB_ACTIONS::deleteFootprint, fpSelectedCondition );
|
||||||
|
|
||||||
ctxMenu.AddSeparator();
|
ctxMenu.AddSeparator();
|
||||||
|
@ -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 )
|
int FOOTPRINT_EDITOR_CONTROL::DeleteFootprint( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
FOOTPRINT_EDIT_FRAME* frame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
|
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::saveAs.MakeEvent() );
|
||||||
Go( &FOOTPRINT_EDITOR_CONTROL::SaveAs, ACTIONS::saveCopyAs.MakeEvent() );
|
Go( &FOOTPRINT_EDITOR_CONTROL::SaveAs, ACTIONS::saveCopyAs.MakeEvent() );
|
||||||
Go( &FOOTPRINT_EDITOR_CONTROL::Revert, ACTIONS::revert.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::DeleteFootprint, PCB_ACTIONS::deleteFootprint.MakeEvent() );
|
||||||
|
|
||||||
Go( &FOOTPRINT_EDITOR_CONTROL::EditFootprint, PCB_ACTIONS::editFootprint.MakeEvent() );
|
Go( &FOOTPRINT_EDITOR_CONTROL::EditFootprint, PCB_ACTIONS::editFootprint.MakeEvent() );
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
int EditFootprint( const TOOL_EVENT& aEvent );
|
int EditFootprint( const TOOL_EVENT& aEvent );
|
||||||
int CutCopyFootprint( const TOOL_EVENT& aEvent );
|
int CutCopyFootprint( const TOOL_EVENT& aEvent );
|
||||||
int PasteFootprint( 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 DeleteFootprint( const TOOL_EVENT& aEvent );
|
||||||
int ImportFootprint( const TOOL_EVENT& aEvent );
|
int ImportFootprint( const TOOL_EVENT& aEvent );
|
||||||
int ExportFootprint( const TOOL_EVENT& aEvent );
|
int ExportFootprint( const TOOL_EVENT& aEvent );
|
||||||
|
|
|
@ -369,6 +369,16 @@ TOOL_ACTION PCB_ACTIONS::editFootprint( "pcbnew.ModuleEditor.editFootprint",
|
||||||
_( "Edit Footprint" ), _( "Show selected footprint on editor canvas" ),
|
_( "Edit Footprint" ), _( "Show selected footprint on editor canvas" ),
|
||||||
BITMAPS::edit );
|
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",
|
TOOL_ACTION PCB_ACTIONS::deleteFootprint( "pcbnew.ModuleEditor.deleteFootprint",
|
||||||
AS_GLOBAL, 0, "",
|
AS_GLOBAL, 0, "",
|
||||||
_( "Delete Footprint from Library" ), _( "Delete Footprint from Library" ),
|
_( "Delete Footprint from Library" ), _( "Delete Footprint from Library" ),
|
||||||
|
|
|
@ -374,6 +374,8 @@ public:
|
||||||
static TOOL_ACTION saveToLibrary;
|
static TOOL_ACTION saveToLibrary;
|
||||||
|
|
||||||
static TOOL_ACTION editFootprint;
|
static TOOL_ACTION editFootprint;
|
||||||
|
static TOOL_ACTION duplicateFootprint;
|
||||||
|
static TOOL_ACTION renameFootprint;
|
||||||
static TOOL_ACTION deleteFootprint;
|
static TOOL_ACTION deleteFootprint;
|
||||||
static TOOL_ACTION cutFootprint;
|
static TOOL_ACTION cutFootprint;
|
||||||
static TOOL_ACTION copyFootprint;
|
static TOOL_ACTION copyFootprint;
|
||||||
|
|
Loading…
Reference in New Issue