cvpcb: Add undo/redo functionality to the associations
This commit is contained in:
parent
402031244d
commit
06abda254a
|
@ -193,6 +193,7 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
m_skipComponentSelect = true;
|
||||
error_msg.Empty();
|
||||
|
||||
bool firstAssoc = true;
|
||||
for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ )
|
||||
{
|
||||
COMPONENT* component = m_netlist.GetComponent( kk );
|
||||
|
@ -232,7 +233,9 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
// If the equivalence is unique, no ambiguity: use the association
|
||||
if( module && equ_is_unique )
|
||||
{
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ) );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ),
|
||||
firstAssoc );
|
||||
firstAssoc = false;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -270,7 +273,8 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
|
||||
if( found )
|
||||
{
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ) );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, equivItem.m_FootprintFPID ), firstAssoc );
|
||||
firstAssoc = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +283,8 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
continue;
|
||||
else if( !fpid_candidate.IsEmpty() )
|
||||
{
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, fpid_candidate ) );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, fpid_candidate ), firstAssoc );
|
||||
firstAssoc = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -291,7 +296,11 @@ void CVPCB_MAINFRAME::AutomaticFootprintMatching()
|
|||
const FOOTPRINT_INFO* module = m_FootprintsList->GetModuleInfo( component->GetFootprintFilters()[0] );
|
||||
|
||||
if( module )
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, component->GetFootprintFilters()[0] ) );
|
||||
{
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( kk, component->GetFootprintFilters()[0] ),
|
||||
firstAssoc );
|
||||
firstAssoc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
*
|
||||
* @return the reversed association
|
||||
*/
|
||||
CVPCB_ASSOCIATION Reverse()
|
||||
CVPCB_ASSOCIATION Reverse() const
|
||||
{
|
||||
return CVPCB_ASSOCIATION( m_componentIndex, m_oldFootprint, m_newFootprint );
|
||||
}
|
||||
|
|
|
@ -404,7 +404,47 @@ void CVPCB_MAINFRAME::OnQuit( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation )
|
||||
void CVPCB_MAINFRAME::UndoAssociation()
|
||||
{
|
||||
if( m_undoList.size() == 0 )
|
||||
return;
|
||||
|
||||
CVPCB_UNDO_REDO_ENTRIES redoEntries;
|
||||
CVPCB_UNDO_REDO_ENTRIES curEntry = m_undoList.back();
|
||||
m_undoList.pop_back();
|
||||
|
||||
// Iterate over the entries to undo
|
||||
for( auto assoc : curEntry )
|
||||
{
|
||||
AssociateFootprint( assoc, true, false );
|
||||
redoEntries.emplace_back( assoc.Reverse() );
|
||||
}
|
||||
|
||||
// Add the redo entries to the redo stack
|
||||
m_redoList.emplace_back( redoEntries );
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::RedoAssociation()
|
||||
{
|
||||
if( m_redoList.size() == 0 )
|
||||
return;
|
||||
|
||||
CVPCB_UNDO_REDO_ENTRIES curEntry = m_redoList.back();
|
||||
m_redoList.pop_back();
|
||||
|
||||
// Iterate over the entries to undo
|
||||
bool firstAssoc = true;
|
||||
for( auto assoc : curEntry )
|
||||
{
|
||||
AssociateFootprint( assoc, firstAssoc );
|
||||
firstAssoc = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation,
|
||||
bool aNewEntry, bool aAddUndoItem )
|
||||
{
|
||||
// Ensure there is data to work with
|
||||
COMPONENT* component;
|
||||
|
@ -417,7 +457,8 @@ void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation
|
|||
if( component == NULL )
|
||||
return;
|
||||
|
||||
LIB_ID fpid = aAssociation.GetNewFootprint();
|
||||
LIB_ID fpid = aAssociation.GetNewFootprint();
|
||||
LIB_ID oldFpid = component->GetFPID();
|
||||
|
||||
// Test for validity of the requested footprint
|
||||
if( !fpid.empty() && !fpid.IsValid() )
|
||||
|
@ -442,6 +483,26 @@ void CVPCB_MAINFRAME::AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation
|
|||
// Update the statusbar and refresh the list
|
||||
DisplayStatus();
|
||||
m_compListBox->Refresh();
|
||||
|
||||
if( !aAddUndoItem )
|
||||
return;
|
||||
|
||||
// Update the undo list
|
||||
if ( aNewEntry )
|
||||
{
|
||||
// Create a new entry for this association
|
||||
CVPCB_UNDO_REDO_ENTRIES newEntry;
|
||||
newEntry.emplace_back( CVPCB_ASSOCIATION( aAssociation.GetComponentIndex(), oldFpid,
|
||||
aAssociation.GetNewFootprint() ) );
|
||||
m_undoList.emplace_back( newEntry );
|
||||
|
||||
// Clear the redo list
|
||||
m_redoList.clear();
|
||||
}
|
||||
else
|
||||
m_undoList.back().emplace_back( CVPCB_ASSOCIATION( aAssociation.GetComponentIndex(),
|
||||
oldFpid, aAssociation.GetNewFootprint() ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -454,9 +515,11 @@ void CVPCB_MAINFRAME::DeleteAll()
|
|||
// Remove all selections to avoid issues when setting the fpids
|
||||
m_compListBox->DeselectAll();
|
||||
|
||||
bool firstAssoc = true;
|
||||
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
|
||||
{
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( i, LIB_ID() ) );
|
||||
AssociateFootprint( CVPCB_ASSOCIATION( i, LIB_ID() ), firstAssoc );
|
||||
firstAssoc = false;
|
||||
}
|
||||
|
||||
// Remove all selections after setting the fpids
|
||||
|
|
|
@ -46,6 +46,12 @@ class FP_LIB_TABLE;
|
|||
|
||||
namespace CV { struct IFACE; }
|
||||
|
||||
// The undo/redo list is composed of vectors of associations
|
||||
typedef std::vector< CVPCB_ASSOCIATION > CVPCB_UNDO_REDO_ENTRIES;
|
||||
|
||||
// The undo list is a vector of undo entries
|
||||
typedef std::vector< CVPCB_UNDO_REDO_ENTRIES > CVPCB_UNDO_REDO_LIST;
|
||||
|
||||
/**
|
||||
* The CvPcb application main window.
|
||||
*/
|
||||
|
@ -170,12 +176,30 @@ public:
|
|||
*/
|
||||
void OnEnterFilteringText( wxCommandEvent& event );
|
||||
|
||||
|
||||
/**
|
||||
* Undo the most recent associations that were performed.
|
||||
*/
|
||||
void UndoAssociation();
|
||||
|
||||
/**
|
||||
* Redo the most recently undone association
|
||||
*/
|
||||
void RedoAssociation();
|
||||
|
||||
/**
|
||||
* Associate a footprint with a specific component in the list.
|
||||
*
|
||||
* Associations can be chained into a single undo/redo step by setting aNewEntry to false
|
||||
* for every association other than the first one. This will create a new list entry for
|
||||
* the first association, and add the subsequent associations to that list.
|
||||
*
|
||||
* @param aAssociation is the association to perform
|
||||
* @param aNewEntry specifies if this association should be a new entry in the undo list
|
||||
* @param aAddUndoItem specifies if an undo item should be created for this association
|
||||
*/
|
||||
void AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation );
|
||||
void AssociateFootprint( const CVPCB_ASSOCIATION& aAssociation, bool aNewEntry = true,
|
||||
bool aAddUndoItem = true );
|
||||
|
||||
void BuildCmpListBox();
|
||||
void BuildFOOTPRINTS_LISTBOX();
|
||||
|
@ -318,6 +342,10 @@ private:
|
|||
ACTION_MENU* m_footprintContextMenu;
|
||||
ACTION_MENU* m_componentContextMenu;
|
||||
|
||||
// Undo/Redo item lists
|
||||
CVPCB_UNDO_REDO_LIST m_undoList;
|
||||
CVPCB_UNDO_REDO_LIST m_redoList;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
|
|
@ -51,6 +51,24 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
|
|||
|
||||
fileMenu->Resolve();
|
||||
|
||||
//-- Preferences menu -----------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, tool );
|
||||
|
||||
auto enableUndoCondition = [ this ] ( const SELECTION& sel )
|
||||
{
|
||||
return m_undoList.size() > 0;
|
||||
};
|
||||
auto enableRedoCondition = [ this ] ( const SELECTION& sel )
|
||||
{
|
||||
return m_redoList.size() > 0;
|
||||
};
|
||||
|
||||
editMenu->AddItem( ACTIONS::undo, enableUndoCondition );
|
||||
editMenu->AddItem( ACTIONS::redo, enableRedoCondition );
|
||||
|
||||
editMenu->Resolve();
|
||||
|
||||
//-- Preferences menu -----------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, tool );
|
||||
|
@ -72,6 +90,7 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
|
|||
//-- Menubar -------------------------------------------------------------
|
||||
//
|
||||
menuBar->Append( fileMenu, _( "&File" ) );
|
||||
menuBar->Append( editMenu, _( "&Edit" ) );
|
||||
menuBar->Append( prefsMenu, _( "&Preferences" ) );
|
||||
AddStandardHelpMenu( menuBar );
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
|
|||
m_mainToolBar->Add( CVPCB_ACTIONS::gotoNextNA );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
m_mainToolBar->Add( ACTIONS::undo );
|
||||
m_mainToolBar->Add( ACTIONS::redo );
|
||||
m_mainToolBar->Add( CVPCB_ACTIONS::autoAssociate );
|
||||
m_mainToolBar->Add( CVPCB_ACTIONS::deleteAll );
|
||||
|
||||
|
@ -86,6 +88,9 @@ void CVPCB_MAINFRAME::SyncToolbars()
|
|||
{
|
||||
#define filterActive( filt ) ( m_filteringOptions & filt )
|
||||
|
||||
m_mainToolBar->Toggle( ACTIONS::undo, m_undoList.size() > 0 );
|
||||
m_mainToolBar->Toggle( ACTIONS::redo, m_redoList.size() > 0 );
|
||||
|
||||
m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyKeywords,
|
||||
filterActive( FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD ) );
|
||||
m_mainToolBar->Toggle( CVPCB_ACTIONS::filterFPbyLibrary,
|
||||
|
|
|
@ -96,6 +96,22 @@ int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::Undo( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->UndoAssociation();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::Redo( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->RedoAssociation();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::Associate( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Get the currently selected footprint
|
||||
|
@ -118,10 +134,12 @@ int CVPCB_CONTROL::Associate( const TOOL_EVENT& aEvent )
|
|||
// Get all the components that are selected and associate them with the current footprint
|
||||
std::vector<unsigned int> sel = m_frame->GetSelectedComponentIndices();
|
||||
|
||||
bool firstAssoc = true;
|
||||
for( auto i : sel )
|
||||
{
|
||||
CVPCB_ASSOCIATION newfp( i, fpid );
|
||||
m_frame->AssociateFootprint( newfp );
|
||||
m_frame->AssociateFootprint( newfp, firstAssoc );
|
||||
firstAssoc = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -174,8 +192,27 @@ int CVPCB_CONTROL::ToPreviousNA( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
SELECTION dummySel;
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( dummySel );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_CONTROL::setTransitions()
|
||||
{
|
||||
// Update the menu
|
||||
Go( &CVPCB_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
|
||||
|
||||
// Run the footprint viewer
|
||||
Go( &CVPCB_CONTROL::ShowFootprintViewer, CVPCB_ACTIONS::showFootprintViewer.MakeEvent() );
|
||||
|
||||
|
@ -189,6 +226,8 @@ void CVPCB_CONTROL::setTransitions()
|
|||
Go( &CVPCB_CONTROL::ToPreviousNA, CVPCB_ACTIONS::gotoPreviousNA.MakeEvent() );
|
||||
|
||||
// Footprint association actions
|
||||
Go( &CVPCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::Associate, CVPCB_ACTIONS::associate.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::AutoAssociate, CVPCB_ACTIONS::autoAssociate.MakeEvent() );
|
||||
|
||||
|
|
|
@ -41,6 +41,20 @@ public:
|
|||
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
/**
|
||||
* Undo the footprint associations most recently done.
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int Undo( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Redo the footprint associations most recently done.
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int Redo( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Associate the selected footprint with the currently selected components.
|
||||
*
|
||||
|
@ -107,6 +121,13 @@ public:
|
|||
*/
|
||||
int ToggleFootprintFilter( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Update the menu to reflect the current tool states.
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/*
|
||||
* Sets up handlers for various events.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue