cvpcb: Replumb the footprint association system
This is in preparation for implementing more association actions and an undo/redo system.
This commit is contained in:
parent
72120e0a96
commit
402031244d
|
@ -40,10 +40,11 @@
|
|||
#include <kicad_string.h>
|
||||
#include <macros.h>
|
||||
|
||||
#include <auto_associate.h>
|
||||
#include <cvpcb.h>
|
||||
#include <cvpcb_association.h>
|
||||
#include <cvpcb_mainframe.h>
|
||||
#include <listboxes.h>
|
||||
#include <auto_associate.h>
|
||||
|
||||
#define QUOTE '\''
|
||||
|
||||
|
@ -231,7 +232,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
// If the equivalence is unique, no ambiguity: use the association
|
||||
if( module && equ_is_unique )
|
||||
{
|
||||
SetNewPkg( equivItem.m_FootprintFPID, kk );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ) );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -269,7 +270,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
|
||||
if( found )
|
||||
{
|
||||
SetNewPkg( equivItem.m_FootprintFPID, kk );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +279,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
continue;
|
||||
else if( !fpid_candidate.IsEmpty() )
|
||||
{
|
||||
SetNewPkg( fpid_candidate, kk );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, fpid_candidate ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -290,9 +291,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
const FOOTPRINT_INFO* module = m_FootprintsList->GetModuleInfo( component->GetFootprintFilters()[0] );
|
||||
|
||||
if( module )
|
||||
{
|
||||
SetNewPkg( component->GetFootprintFilters()[0], kk );
|
||||
}
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, component->GetFootprintFilters()[0] ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
|
||||
//
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
class FOOTPRINT_EQUIVALENCE
|
||||
{
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
|
||||
* Copyright (C) 2019 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 as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CVPCB_ASSOCIATION_H
|
||||
#define CVPCB_ASSOCIATION_H
|
||||
|
||||
#include <lib_id.h>
|
||||
#include <utf8.h>
|
||||
|
||||
/**
|
||||
* A class to define a footprint association to be made in cvpcb.
|
||||
*/
|
||||
class CVPCB_ASSOCIATION
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create an association event that contains all the information needed to modify the footprint
|
||||
* association of a component in cvpcb.
|
||||
*
|
||||
* @param aComponentIndex is the index of the component to change
|
||||
* @param aNewFootprint is the new footprint to give to the component
|
||||
* @param aOldFootprint is the old footprint from the component
|
||||
*/
|
||||
CVPCB_ASSOCIATION(
|
||||
unsigned int aComponentIndex, LIB_ID aNewFootprint, LIB_ID aOldFootprint = LIB_ID() ) :
|
||||
m_componentIndex( aComponentIndex ),
|
||||
m_newFootprint( aNewFootprint ),
|
||||
m_oldFootprint( aOldFootprint )
|
||||
{}
|
||||
|
||||
CVPCB_ASSOCIATION(
|
||||
unsigned int aComponentIndex, wxString aNewFootprint, wxString aOldFootprint = "" ) :
|
||||
m_componentIndex( aComponentIndex )
|
||||
{
|
||||
m_newFootprint.Parse( aNewFootprint, LIB_ID::ID_PCB );
|
||||
m_oldFootprint.Parse( aOldFootprint, LIB_ID::ID_PCB );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the association.
|
||||
*
|
||||
* @return the reversed association
|
||||
*/
|
||||
CVPCB_ASSOCIATION Reverse()
|
||||
{
|
||||
return CVPCB_ASSOCIATION( m_componentIndex, m_oldFootprint, m_newFootprint );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the component to modify the association of.
|
||||
*
|
||||
* @return the index of the component
|
||||
*/
|
||||
unsigned int GetComponentIndex() const
|
||||
{
|
||||
return m_componentIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new footprint to associate to the component.
|
||||
*
|
||||
* @return the LIB_ID of the new footprint
|
||||
*/
|
||||
LIB_ID GetNewFootprint() const
|
||||
{
|
||||
return m_newFootprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the old footprint of the component
|
||||
*
|
||||
* @return the LIB_ID of the old footprint
|
||||
*/
|
||||
LIB_ID GetOldFootprint() const
|
||||
{
|
||||
return m_oldFootprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the footprint that should be associated with the component
|
||||
*
|
||||
* @param aNewFootprint is the LIB_ID of the new footprint
|
||||
*/
|
||||
void SetNewFootprint( const LIB_ID& aNewFootprint )
|
||||
{
|
||||
m_newFootprint = aNewFootprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the footprint that was associated with the component before this association event
|
||||
*
|
||||
* @param aOldFootprint is the LIB_ID of the old footprint
|
||||
*/
|
||||
void SetOldFootprint( const LIB_ID& aOldFootprint )
|
||||
{
|
||||
m_oldFootprint = aOldFootprint;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
unsigned int m_componentIndex;
|
||||
LIB_ID m_newFootprint;
|
||||
LIB_ID m_oldFootprint;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -44,6 +44,7 @@
|
|||
#include <wx/statline.h>
|
||||
|
||||
#include <cvpcb.h>
|
||||
#include <cvpcb_association.h>
|
||||
#include <cvpcb_id.h>
|
||||
#include <cvpcb_mainframe.h>
|
||||
#include <display_footprints_frame.h>
|
||||
|
@ -403,6 +404,47 @@ void CVPCB_MAINFRAME::OnQuit( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation )
|
||||
{
|
||||
// Ensure there is data to work with
|
||||
COMPONENT* component;
|
||||
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
component = m_netlist.GetComponent( aAssociation.GetComponentIndex() );
|
||||
|
||||
if( component == NULL )
|
||||
return;
|
||||
|
||||
LIB_ID fpid = aAssociation.GetNewFootprint();
|
||||
|
||||
// Test for validity of the requested footprint
|
||||
if( !fpid.empty() && !fpid.IsValid() )
|
||||
{
|
||||
wxString msg =
|
||||
wxString::Format( _( "\"%s\" is not a valid footprint." ), fpid.Format().wx_str() );
|
||||
DisplayErrorMessage( this, msg );
|
||||
}
|
||||
|
||||
// Set the new footprint
|
||||
component->SetFPID( fpid );
|
||||
|
||||
// create the new component description and set it
|
||||
wxString description = wxString::Format( CMP_FORMAT, aAssociation.GetComponentIndex() + 1,
|
||||
GetChars( component->GetReference() ), GetChars( component->GetValue() ),
|
||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||
m_compListBox->SetString( aAssociation.GetComponentIndex(), description );
|
||||
|
||||
// Mark the data as being modified
|
||||
m_modified = true;
|
||||
|
||||
// Update the statusbar and refresh the list
|
||||
DisplayStatus();
|
||||
m_compListBox->Refresh();
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::DeleteAll()
|
||||
{
|
||||
if( IsOK( this, _( "Delete all associations?" ) ) )
|
||||
|
@ -414,10 +456,7 @@ void CVPCB_MAINFRAME::DeleteAll()
|
|||
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
LIB_ID fpid;
|
||||
|
||||
m_netlist.GetComponent( i )->SetFPID( fpid );
|
||||
SetNewPkg( wxEmptyString );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( i, LIB_ID() ) );
|
||||
}
|
||||
|
||||
// Remove all selections after setting the fpids
|
||||
|
@ -853,6 +892,29 @@ COMPONENT* CVPCB_MAINFRAME::GetSelectedComponent()
|
|||
}
|
||||
|
||||
|
||||
std::vector<unsigned int> CVPCB_MAINFRAME::GetSelectedComponentIndices()
|
||||
{
|
||||
std::vector<unsigned int> idx;
|
||||
|
||||
// Check to see if anything is selected
|
||||
if( m_compListBox->GetSelectedItemCount() < 1 )
|
||||
return idx;
|
||||
|
||||
// Get the components
|
||||
int lastIdx = m_compListBox->GetFirstSelected();
|
||||
idx.emplace_back( lastIdx );
|
||||
|
||||
lastIdx = m_compListBox->GetNextSelected( lastIdx );
|
||||
while( lastIdx > 0 )
|
||||
{
|
||||
idx.emplace_back( lastIdx );
|
||||
lastIdx = m_compListBox->GetNextSelected( lastIdx );
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
DISPLAY_FOOTPRINTS_FRAME* CVPCB_MAINFRAME::GetFootprintViewerFrame()
|
||||
{
|
||||
// returns the Footprint Viewer frame, if exists, or NULL
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <wx/listctrl.h>
|
||||
|
||||
#include <auto_associate.h>
|
||||
#include <cvpcb_association.h>
|
||||
#include <listboxes.h>
|
||||
#include <tool/action_menu.h>
|
||||
|
||||
|
@ -170,21 +171,11 @@ public:
|
|||
void OnEnterFilteringText( wxCommandEvent& event );
|
||||
|
||||
/**
|
||||
* Function SetNewPkg
|
||||
* set the footprint name for all selected components in component list
|
||||
* and selects the next component.
|
||||
* @param aFootprintName = the new footprint name
|
||||
*/
|
||||
void SetNewPkg( const wxString& aFootprintName );
|
||||
|
||||
/**
|
||||
* Function SetNewPkg
|
||||
* Set the footprint name for the component of position aIndex in the component list
|
||||
* Associate a footprint with a specific component in the list.
|
||||
*
|
||||
* @param aFootprintName = the new footprint name
|
||||
* @param aIndex = the index of the component to modify in the component list
|
||||
* @param aAssociation is the association to perform
|
||||
*/
|
||||
void SetNewPkg( const wxString& aFootprintName, int aIndex );
|
||||
void AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation );
|
||||
|
||||
void BuildCmpListBox();
|
||||
void BuildFOOTPRINTS_LISTBOX();
|
||||
|
@ -286,6 +277,13 @@ public:
|
|||
|
||||
COMPONENT* GetSelectedComponent();
|
||||
|
||||
/**
|
||||
* Get the indices for all the selected components in the components listbox.
|
||||
*
|
||||
* @return a vector containing all the indices
|
||||
*/
|
||||
std::vector<unsigned int> GetSelectedComponentIndices();
|
||||
|
||||
/**
|
||||
* @return the LIB_ID of the selected footprint in footprint listview
|
||||
* or a empty string if no selection
|
||||
|
|
|
@ -227,9 +227,7 @@ void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
|
|||
|
||||
void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
|
||||
{
|
||||
wxString footprintName = GetSelectedFootprint();
|
||||
|
||||
GetParent()->SetNewPkg( footprintName );
|
||||
GetParent()->GetToolManager()->RunAction( CVPCB_ACTIONS::associate, true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,86 +42,6 @@
|
|||
#include <fp_conflict_assignment_selector.h>
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
|
||||
{
|
||||
COMPONENT* component;
|
||||
int componentIndex;
|
||||
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
// If no component is selected, select the first one
|
||||
if( m_compListBox->GetFirstSelected() < 0 )
|
||||
{
|
||||
componentIndex = 0;
|
||||
m_compListBox->SetSelection( componentIndex, true );
|
||||
}
|
||||
|
||||
// iterate over the selection
|
||||
while( m_compListBox->GetFirstSelected() != -1 )
|
||||
{
|
||||
// Get the component for the current iteration
|
||||
componentIndex = m_compListBox->GetFirstSelected();
|
||||
component = m_netlist.GetComponent( componentIndex );
|
||||
|
||||
if( component == NULL )
|
||||
return;
|
||||
|
||||
SetNewPkg( aFootprintName, componentIndex );
|
||||
|
||||
m_compListBox->SetSelection( componentIndex, false );
|
||||
}
|
||||
|
||||
// select the next component, if there is one
|
||||
if( componentIndex < (m_compListBox->GetCount() - 1) )
|
||||
componentIndex++;
|
||||
|
||||
m_compListBox->SetSelection( componentIndex, true );
|
||||
|
||||
// update the statusbar
|
||||
DisplayStatus();
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
|
||||
{
|
||||
COMPONENT* component;
|
||||
|
||||
if( m_netlist.IsEmpty() )
|
||||
return;
|
||||
|
||||
component = m_netlist.GetComponent( aIndex );
|
||||
|
||||
if( component == NULL )
|
||||
return;
|
||||
|
||||
LIB_ID fpid;
|
||||
|
||||
if( !aFootprintName.IsEmpty() )
|
||||
{
|
||||
wxCHECK_RET( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0,
|
||||
wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) );
|
||||
}
|
||||
|
||||
component->SetFPID( fpid );
|
||||
|
||||
// create the new component description
|
||||
wxString description = wxString::Format( CMP_FORMAT, aIndex + 1,
|
||||
GetChars( component->GetReference() ),
|
||||
GetChars( component->GetValue() ),
|
||||
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
|
||||
|
||||
// Set the new description and deselect the processed component
|
||||
m_compListBox->SetString( aIndex, description );
|
||||
|
||||
// Mark this "session" as modified
|
||||
m_modified = true;
|
||||
|
||||
// update the statusbar
|
||||
DisplayStatus();
|
||||
}
|
||||
|
||||
|
||||
/// Return true if the resultant LIB_ID has a certain nickname. The guess
|
||||
/// is only made if this footprint resides in only one library.
|
||||
/// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches
|
||||
|
|
|
@ -78,6 +78,12 @@ TOOL_ACTION CVPCB_ACTIONS::gotoPreviousNA( "cvpcb.Control.GotoPreviousNA", AS_GL
|
|||
|
||||
|
||||
// Actions to modify component associations
|
||||
TOOL_ACTION CVPCB_ACTIONS::associate( "cvpcb.Control.Associate", AS_GLOBAL,
|
||||
0, "",
|
||||
_( "Associate footprint" ),
|
||||
_( "Associate selected footprint with selected components" ),
|
||||
auto_associe_xpm );
|
||||
|
||||
TOOL_ACTION CVPCB_ACTIONS::autoAssociate( "cvpcb.Control.AutoAssociate", AS_GLOBAL,
|
||||
0, "",
|
||||
_( "Automatically associate footprints" ),
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <confirm.h>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <kiface_i.h>
|
||||
#include <kiway_express.h>
|
||||
#include <lib_id.h>
|
||||
#include <tool/actions.h>
|
||||
|
||||
#include <cvpcb_mainframe.h>
|
||||
|
@ -94,6 +96,38 @@ int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::Associate( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Get the currently selected footprint
|
||||
LIB_ID fpid;
|
||||
wxString fp = m_frame->GetSelectedFootprint();
|
||||
fpid.Parse( fp, LIB_ID::ID_PCB );
|
||||
|
||||
// Ignore the action if the footprint is empty (nothing selected)
|
||||
if( fpid.empty() )
|
||||
return 0;
|
||||
|
||||
// Test for validity of the requested footprint
|
||||
if( !fpid.IsValid() )
|
||||
{
|
||||
wxString msg =
|
||||
wxString::Format( _( "\"%s\" is not a valid footprint." ), fpid.Format().wx_str() );
|
||||
DisplayErrorMessage( m_frame, msg );
|
||||
}
|
||||
|
||||
// Get all the components that are selected and associate them with the current footprint
|
||||
std::vector<unsigned int> sel = m_frame->GetSelectedComponentIndices();
|
||||
|
||||
for( auto i : sel )
|
||||
{
|
||||
CVPCB_ASSOCIATION newfp( i, fpid );
|
||||
m_frame->AssociateFootprint( newfp );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::AutoAssociate( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->AutomaticFootprintMatching();
|
||||
|
@ -155,6 +189,7 @@ void CVPCB_CONTROL::setTransitions()
|
|||
Go( &CVPCB_CONTROL::ToPreviousNA, CVPCB_ACTIONS::gotoPreviousNA.MakeEvent() );
|
||||
|
||||
// Footprint association actions
|
||||
Go( &CVPCB_CONTROL::Associate, CVPCB_ACTIONS::associate.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::AutoAssociate, CVPCB_ACTIONS::autoAssociate.MakeEvent() );
|
||||
|
||||
// Filter the footprints
|
||||
|
|
|
@ -41,6 +41,13 @@ public:
|
|||
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
/**
|
||||
* Associate the selected footprint with the currently selected components.
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int Associate( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Perform automatic footprint association.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue