ModEdit Save should save back to board if that's where the FP came from.

Use Save As... if you want to put it in a library.

Fixes: lp:1788924
* https://bugs.launchpad.net/kicad/+bug/1788924
This commit is contained in:
Jeff Young 2018-08-25 16:12:08 +01:00
parent 21eea1f567
commit e55547223e
9 changed files with 146 additions and 177 deletions

View File

@ -113,7 +113,6 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_TOOL( ID_MODEDIT_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard )
EVT_TOOL( ID_MODEDIT_INSERT_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList )
EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList )
@ -183,8 +182,6 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard )
EVT_UPDATE_UI( ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard )
EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateSelectTool )
EVT_UPDATE_UI( ID_ZOOM_SELECTION, FOOTPRINT_EDIT_FRAME::OnUpdateSelectTool )
@ -350,19 +347,19 @@ BOARD_ITEM_CONTAINER* FOOTPRINT_EDIT_FRAME::GetModel() const
}
LIB_ID FOOTPRINT_EDIT_FRAME::getTargetLibId() const
LIB_ID FOOTPRINT_EDIT_FRAME::getTargetFPId() const
{
LIB_ID id = m_treePane->GetLibTree()->GetSelectedLibId();
wxString nickname = id.GetLibNickname();
if( nickname.IsEmpty() )
return GetCurrentLibId();
return GetCurrentFPId();
return id;
}
LIB_ID FOOTPRINT_EDIT_FRAME::GetCurrentLibId() const
LIB_ID FOOTPRINT_EDIT_FRAME::GetCurrentFPId() const
{
MODULE* module = GetBoard()->m_Modules;
@ -373,9 +370,17 @@ LIB_ID FOOTPRINT_EDIT_FRAME::GetCurrentLibId() const
}
bool FOOTPRINT_EDIT_FRAME::IsCurrentFPFromBoard() const
{
MODULE* module = GetBoard()->m_Modules;
return ( module && module->GetLink() > 0 );
}
void FOOTPRINT_EDIT_FRAME::retainLastFootprint()
{
LIB_ID id = GetCurrentLibId();
LIB_ID id = GetCurrentFPId();
if( id.IsValid() )
{
@ -567,7 +572,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( getTargetLibId().IsValid() );
aEvent.Enable( getTargetFPId().IsValid() );
}
@ -579,7 +584,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs( wxUpdateUIEvent& aEvent )
{
LIB_ID libId = getTargetLibId();
LIB_ID libId = getTargetFPId();
const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName();
@ -622,32 +627,6 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent
}
void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent )
{
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
MODULE* module_in_edit = GetBoard()->m_Modules;
bool canReplace = frame && module_in_edit && module_in_edit->GetLink();
if( canReplace ) // this is not a new module, but verify if the source is still on board
{
BOARD* mainpcb = frame->GetBoard();
MODULE* source_module = mainpcb->m_Modules;
// search if the source module was not deleted:
for( ; source_module != NULL; source_module = source_module->Next() )
{
if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
break;
}
canReplace = ( source_module != NULL );
}
aEvent.Enable( canReplace );
}
void FOOTPRINT_EDIT_FRAME::ReFillLayerWidget()
{
@ -750,7 +729,7 @@ void FOOTPRINT_EDIT_FRAME::OnModify()
void FOOTPRINT_EDIT_FRAME::updateTitle()
{
wxString title = _( "Footprint Library Editor" );
LIB_ID fpid = GetCurrentLibId();
LIB_ID fpid = GetCurrentFPId();
bool writable = true;
if( fpid.IsValid() )
@ -832,7 +811,7 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
{
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
LIB_ID target = getTargetLibId();
LIB_ID target = getTargetFPId();
bool targetSelected = ( target == m_treePane->GetLibTree()->GetSelectedLibId() );
// Sync FOOTPRINT_INFO list to the libraries on disk

View File

@ -61,6 +61,8 @@ public:
///> @copydoc PCB_BASE_EDIT_FRAME::GetModel()
BOARD_ITEM_CONTAINER* GetModel() const override;
bool IsCurrentFPFromBoard() const;
BOARD_DESIGN_SETTINGS& GetDesignSettings() const override;
void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ) override;
@ -206,7 +208,6 @@ public:
void OnUpdateSaveAs( wxUpdateUIEvent& aEvent );
void OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent );
void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent );
void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent );
///> @copydoc PCB_BASE_EDIT_FRAME::OnEditItemRequest()
void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) override;
@ -230,6 +231,7 @@ public:
*/
bool SaveFootprint( MODULE* aModule );
bool SaveFootprintAs( MODULE* aModule );
bool SaveFootprintToBoard( bool aAddNew );
/**
* Virtual Function OnModify()
@ -294,10 +296,10 @@ public:
BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
/// Return the LIB_ID of the part selected in the footprint or the part being edited.
LIB_ID getTargetLibId() const;
LIB_ID getTargetFPId() const;
/// Return the LIB_ID of the part being edited.
LIB_ID GetCurrentLibId() const;
LIB_ID GetCurrentFPId() const;
void RemoveStruct( EDA_ITEM* Item );

View File

@ -276,9 +276,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_DELETE_PART:
if( DeleteModuleFromLibrary( LoadFootprint( getTargetLibId() ) ) )
if( DeleteModuleFromLibrary( LoadFootprint( getTargetFPId() ) ) )
{
if( getTargetLibId() == GetCurrentLibId() )
if( getTargetFPId() == GetCurrentFPId() )
Clear_Pcb( false );
SyncLibraryTree( true );
@ -392,7 +392,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_SAVE:
if( getTargetLibId() == GetCurrentLibId() )
if( getTargetFPId() == GetCurrentFPId() )
{
if( SaveFootprint( GetBoard()->m_Modules ) )
{
@ -411,22 +411,22 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_SAVE_AS:
if( getTargetLibId().GetLibItemName().empty() )
if( getTargetFPId().GetLibItemName().empty() )
{
// Save Library As
const wxString& libName = getTargetLibId().GetLibNickname();
const wxString& libName = getTargetFPId().GetLibNickname();
if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) )
SyncLibraryTree( true );
}
else
{
// Save Footprint As
MODULE* footprint = LoadFootprint( getTargetLibId() );
MODULE* footprint = LoadFootprint( getTargetFPId() );
if( footprint && SaveFootprintAs( footprint ) )
{
SyncLibraryTree( false );
if( getTargetLibId() == GetCurrentLibId() )
if( getTargetFPId() == GetCurrentFPId() )
{
m_toolManager->GetView()->Update( GetBoard()->m_Modules );
@ -444,93 +444,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
case ID_MODEDIT_UPDATE_MODULE_IN_BOARD:
{
// update module in the current board,
// not just add it to the board with total disregard for the netlist...
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
{
DisplayErrorMessage( this, _("No board currently open." ) );
break;
}
BOARD* mainpcb = pcbframe->GetBoard();
MODULE* source_module = NULL;
MODULE* module_in_edit = GetBoard()->m_Modules;
// Search the old module (source) if exists
// Because this source could be deleted when editing the main board...
if( module_in_edit->GetLink() ) // this is not a new module ...
{
source_module = mainpcb->m_Modules;
for( ; source_module != NULL; source_module = source_module->Next() )
{
if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
break;
}
}
if( ( source_module == NULL )
&& ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found
{
wxString msg;
msg.Printf( _( "Unable to find the footprint source on the main board" ) );
msg << _( "\nCannot update the footprint" );
DisplayError( this, msg );
break;
}
if( ( source_module != NULL )
&& ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found
{
wxString msg;
msg.Printf( _( "A footprint source was found on the main board" ) );
msg << _( "\nCannot insert this footprint" );
DisplayError( this, msg );
break;
}
m_toolManager->RunAction( PCB_ACTIONS::selectionClear, true );
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
// Create the "new" module
MODULE* newmodule = new MODULE( *module_in_edit );
newmodule->SetParent( mainpcb );
newmodule->SetLink( 0 );
if( source_module ) // this is an update command
{
// In the main board,
// the new module replace the old module (pos, orient, ref, value
// and connexions are kept)
// and the source_module (old module) is deleted
pcbframe->Exchange_Module( source_module, newmodule, commit );
newmodule->SetTimeStamp( module_in_edit->GetLink() );
commit.Push( wxT( "Update module" ) );
}
else // This is an insert command
{
wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
commit.Add( newmodule );
pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
pcbframe->PlaceModule( newmodule, NULL );
newmodule->SetPosition( wxPoint( 0, 0 ) );
pcbframe->SetCrossHairPosition( cursor_pos );
newmodule->SetTimeStamp( GetNewTimeStamp() );
commit.Push( wxT( "Insert module" ) );
}
newmodule->ClearFlags();
GetScreen()->ClrModify();
pcbframe->SetCurItem( NULL );
// @todo LEGACY should be unnecessary
mainpcb->m_Status_Pcb = 0;
}
SaveFootprintToBoard( true );
break;
case ID_MODEDIT_IMPORT_PART:
@ -551,7 +465,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_EXPORT_PART:
Export_Module( LoadFootprint( getTargetLibId() ) );
Export_Module( LoadFootprint( getTargetFPId() ) );
break;
case ID_MODEDIT_CREATE_NEW_LIB:

View File

@ -43,10 +43,11 @@
#include <fp_lib_table.h>
#include <validators.h>
#include <dialog_text_entry.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <class_board.h>
#include <class_module.h>
#include <board_commit.h>
#include <pcbnew.h>
#include <footprint_edit_frame.h>
#include <wildcards_and_files_ext.h>
@ -670,6 +671,11 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
wxString libraryName = aModule->GetFPID().GetLibNickname();
wxString footprintName = aModule->GetFPID().GetLibItemName();
if( aModule->GetLink() )
{
return SaveFootprintToBoard( false );
}
if( libraryName.IsEmpty() || footprintName.IsEmpty() )
return SaveFootprintAs( aModule );
@ -707,6 +713,88 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
}
bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
{
// update module in the current board,
// not just add it to the board with total disregard for the netlist...
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
{
DisplayErrorMessage( this, _("No board currently open." ) );
return false;
}
BOARD* mainpcb = pcbframe->GetBoard();
MODULE* source_module = NULL;
MODULE* module_in_edit = GetBoard()->m_Modules;
// Search the old module (source) if exists
// Because this source could be deleted when editing the main board...
if( module_in_edit->GetLink() ) // this is not a new module ...
{
source_module = mainpcb->m_Modules;
for( ; source_module != NULL; source_module = source_module->Next() )
{
if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
break;
}
}
if( !aAddNew && source_module == NULL ) // source not found
{
DisplayError( this, _( "Unable to find the footprint on the main board.\nCannot save." ) );
return false;
}
if( aAddNew && source_module != NULL )
{
DisplayError( this, _( "Footprint already exists on board." ) );
return false;
}
m_toolManager->RunAction( PCB_ACTIONS::selectionClear, true );
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
// Create the "new" module
MODULE* newmodule = new MODULE( *module_in_edit );
newmodule->SetParent( mainpcb );
newmodule->SetLink( 0 );
if( source_module ) // this is an update command
{
// In the main board,
// the new module replace the old module (pos, orient, ref, value
// and connexions are kept)
// and the source_module (old module) is deleted
pcbframe->Exchange_Module( source_module, newmodule, commit );
newmodule->SetTimeStamp( module_in_edit->GetLink() );
commit.Push( wxT( "Update module" ) );
}
else // This is an insert command
{
wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
commit.Add( newmodule );
pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
pcbframe->PlaceModule( newmodule, NULL );
newmodule->SetPosition( wxPoint( 0, 0 ) );
pcbframe->SetCrossHairPosition( cursor_pos );
newmodule->SetTimeStamp( GetNewTimeStamp() );
commit.Push( wxT( "Insert module" ) );
}
newmodule->ClearFlags();
pcbframe->SetCurItem( NULL );
// @todo LEGACY should be unnecessary
mainpcb->m_Status_Pcb = 0;
return true;
}
bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule )
{
if( aModule == NULL )

View File

@ -153,13 +153,13 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
}
auto node = ToNode( aItem );
wxASSERT( node );
switch( aCol )
{
case 0:
// mark modified part with an asterix
if( node->LibId == m_frame->GetCurrentLibId() && m_frame->GetScreen()->IsModify() )
if( node->LibId == m_frame->GetCurrentFPId() && !m_frame->IsCurrentFPFromBoard()
&& m_frame->GetScreen()->IsModify() )
aVariant = node->Name + " *";
else
aVariant = node->Name;
@ -192,45 +192,37 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
switch( node->Type )
{
case LIB_TREE_NODE::LIB:
if( node->Name == m_frame->GetCurrentFPId().GetLibNickname() )
{
#ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
// This works reasonably well in dark themes, and quite poorly in light ones....
if( node->Name == m_frame->GetCurrentLibId().GetLibNickname() )
{
// The native wxGTK+ impl ignores background colour, so set the text colour
// instead. Works reasonably well in dark themes, less well in light ones....
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified libs with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModified() );
}
#else
// mark the current library with background color
if( node->Name == m_frame->GetCurrentLibId().GetLibNickname() )
{
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified libs with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModify() );
}
#endif
// mark modified libs with bold font
if( m_frame->GetScreen()->IsModify() && !m_frame->IsCurrentFPFromBoard() )
aAttr.SetBold( true );
}
break;
case LIB_TREE_NODE::LIBID:
if( node->LibId == m_frame->GetCurrentFPId() )
{
#ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
// This works reasonably well in dark themes, and quite poorly in light ones....
if( node->LibId == m_frame->GetCurrentLibId() )
{
// The native wxGTK+ impl ignores background colour, so set the text colour
// instead. Works reasonably well in dark themes, less well in light ones....
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified part with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModified() );
}
#else
// mark the current part with background color
if( node->LibId == m_frame->GetCurrentLibId() )
{
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified part with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModify() );
}
#endif
// mark modified part with bold font
if( m_frame->GetScreen()->IsModify() && !m_frame->IsCurrentFPFromBoard() )
aAttr.SetBold( true );
}
break;
default:

View File

@ -142,9 +142,13 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
// Put it in orientation 0,
// because this is the default orientation in ModEdit, and in libs
Rotate_Module( NULL, newModule, 0, false );
GetScreen()->ClrModify();
Zoom_Automatique( false );
m_adapter->SetPreselectNode( newModule->GetFPID(), 0 );
GetScreen()->ClearUndoRedoList();
GetScreen()->ClrModify();
if( IsGalCanvasActive() )
updateView();
m_canvas->Refresh();

View File

@ -85,7 +85,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
KiBitmap( save_xpm ) );
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_AS,
_( "Save a Copy &As..." ),
_( "Save &As..." ),
_( "Save a copy to a new name and/or location" ),
KiBitmap( save_as_xpm ) );
@ -386,11 +386,6 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
_( "Load a footprint from the current board into the editor" ),
KiBitmap( load_module_board_xpm ) );
AddMenuItem( toolsMenu, ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
_( "&Update Footprint on PCB" ),
_( "Push updated footprint through to current board" ),
KiBitmap( update_module_board_xpm ) );
AddMenuItem( toolsMenu, ID_MODEDIT_INSERT_MODULE_IN_BOARD,
_( "&Insert Footprint on PCB" ),
_( "Insert footprint onto current board" ),

View File

@ -357,7 +357,6 @@ enum pcbnew_ids
ID_MODEDIT_PAD_SETTINGS,
ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
ID_MODEDIT_INSERT_MODULE_IN_BOARD,
ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
ID_MODEDIT_EDIT_MODULE_PROPERTIES,
ID_MODEDIT_TRANSFORM_MODULE,
ID_MODEDIT_MODULE_ROTATE,

View File

@ -101,10 +101,6 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
KiScaledBitmap( load_module_board_xpm, this ),
_( "Load footprint from current board" ) );
m_mainToolBar->AddTool( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, wxEmptyString,
KiScaledBitmap( update_module_board_xpm, this ),
_( "Update footprint into current board" ) );
m_mainToolBar->AddTool( ID_MODEDIT_INSERT_MODULE_IN_BOARD, wxEmptyString,
KiScaledBitmap( insert_module_board_xpm, this ),
_( "Insert footprint into current board" ) );