Sync Sheet Pins: Synchronizes all selected rows.

This commit is contained in:
Ethan Chien 2024-12-31 02:52:09 +08:00
parent b36f67853c
commit b03c591a4b
8 changed files with 127 additions and 65 deletions

View File

@ -40,14 +40,12 @@
#include <sch_drawing_tools.h>
DIALOG_SYNC_SHEET_PINS::DIALOG_SYNC_SHEET_PINS( wxWindow* aParent,
std::list<SCH_SHEET_PATH> aSheetPath,
std::shared_ptr<SHEET_SYNCHRONIZATION_AGENT> aAgent ) :
DIALOG_SYNC_SHEET_PINS_BASE( aParent ),
m_agent( std::move( aAgent ) ),
m_lastEditSheet( nullptr ),
m_placeItemKind( PlaceItemKind::UNDEFINED ),
m_placementTemplate( nullptr )
DIALOG_SYNC_SHEET_PINS::DIALOG_SYNC_SHEET_PINS(
wxWindow* aParent, std::list<SCH_SHEET_PATH> aSheetPath,
std::shared_ptr<SHEET_SYNCHRONIZATION_AGENT> aAgent ) :
DIALOG_SYNC_SHEET_PINS_BASE( aParent ), m_agent( std::move( aAgent ) ),
m_lastEditSheet( nullptr ), m_placeItemKind( PlaceItemKind::UNDEFINED ),
m_currentTemplate( nullptr )
{
wxImageList* imageList = new wxImageList( SYNC_SHEET_PIN_PREFERENCE::NORMAL_WIDTH,
SYNC_SHEET_PIN_PREFERENCE::NORMAL_HEIGHT );
@ -135,21 +133,31 @@ void DIALOG_SYNC_SHEET_PINS::OnClose( wxCloseEvent& aEvent )
void DIALOG_SYNC_SHEET_PINS::EndPlaceItem( EDA_ITEM* aNewItem )
{
auto post_end_place_item = std::shared_ptr<std::nullptr_t>( nullptr,
[&]( std::nullptr_t )
{
m_placeItemKind =
PlaceItemKind::UNDEFINED;
m_placementTemplate = nullptr;
} );
if( !aNewItem )
return;
auto post_end_place_item =
std::shared_ptr<std::nullptr_t>( nullptr,
[&]( std::nullptr_t )
{
m_placementTemplateSet.erase( m_currentTemplate );
if( m_placementTemplateSet.empty() )
{
EndPlacement();
}
else
{
m_currentTemplate =
*m_placementTemplateSet.begin();
}
} );
if( m_lastEditSheet && m_panels.find( m_lastEditSheet ) != m_panels.end() )
{
auto& panel = m_panels[m_lastEditSheet];
auto template_item = static_cast<SCH_HIERLABEL*>( m_placementTemplate );
auto template_item = static_cast<SCH_HIERLABEL*>( m_currentTemplate );
auto new_item = static_cast<SCH_HIERLABEL*>( aNewItem );
//Usr may edit the name or shape while placing the new item , do sync if either differs
@ -175,21 +183,34 @@ void DIALOG_SYNC_SHEET_PINS::EndPlaceItem( EDA_ITEM* aNewItem )
panel->GetModel( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL )->DoNotify();
}
}
void DIALOG_SYNC_SHEET_PINS::BeginPlaceItem( SCH_SHEET* aSheet, PlaceItemKind aKind,
EDA_ITEM* aTemplate )
void DIALOG_SYNC_SHEET_PINS::PreparePlacementTemplate(
SCH_SHEET* aSheet, PlaceItemKind aKind, std::set<EDA_ITEM*> const& aPlacementTemplateSet )
{
if( aPlacementTemplateSet.empty() )
return;
m_lastEditSheet = aSheet;
m_placeItemKind = aKind;
m_placementTemplate = aTemplate;
m_placementTemplateSet = aPlacementTemplateSet;
m_currentTemplate = *m_placementTemplateSet.begin();
}
SCH_HIERLABEL* DIALOG_SYNC_SHEET_PINS::GetPlacementTemplate() const
{
if( !m_placementTemplate )
if( !m_currentTemplate )
return {};
return static_cast<SCH_HIERLABEL*>( m_placementTemplate );
return static_cast<SCH_HIERLABEL*>( m_currentTemplate );
}
bool DIALOG_SYNC_SHEET_PINS::CanPlaceMore() const
{
return !m_placementTemplateSet.empty();
}
void DIALOG_SYNC_SHEET_PINS::EndPlacement()
{
m_placementTemplateSet.clear();
m_placeItemKind = PlaceItemKind::UNDEFINED;
m_currentTemplate = nullptr;
}

View File

@ -57,16 +57,15 @@ public:
void OnClose( wxCloseEvent& aEvent );
void EndPlaceItem( EDA_ITEM* aNewItem );
/**
* Start place a new #SHEET_PIN/#HIERLABEL.
*
* @param aSheet The sheet instance
* @param aKind SHEET_PIN / HIERLABEL
* @param aTemplate The template used for the new SHEET_PIN / HIERLABEL
* @brief Either selected HIERLABELs or SHEET_PINs will be used as templates for placing the new ones.
*
* @param aSheet The sheet where the new HIERLABELs or SHEET_PINs will be placed. For SHEET_PINs, it's the corresponding sheet symbol
* @param aKind Either PlaceItemKind::HIERLABEL or PlaceItemKind::SHEET_PIN
* @param aPlacementTemplateSet All the selected HIERLABELs or SHEET_PINs
*/
void BeginPlaceItem( SCH_SHEET* aSheet, PlaceItemKind aKind, EDA_ITEM* aTemplate );
void PreparePlacementTemplate( SCH_SHEET* aSheet, PlaceItemKind aKind,
std::set<EDA_ITEM*> const& aPlacementTemplateSet );
/**
* Get the Placement Template SHEET_PIN / HIERLABEL used for place a new #HIERLABEL/#SHEET_PIN.
@ -75,6 +74,19 @@ public:
*/
SCH_HIERLABEL* GetPlacementTemplate() const;
/**
* @brief End place a new #HIERLABEL/#SHEET_PIN , and add the new item to the corresponding table.
*
* @param aNewItem The new #HIERLABEL/#SHEET_PIN to be placed.
*/
void EndPlaceItem( EDA_ITEM* aNewItem );
/**
* @brief Check if there are more items to be placed.
*/
bool CanPlaceMore() const;
void EndPlacement();
private:
//It's the agent that performs modification and placement
@ -84,7 +96,8 @@ private:
//The same sheet may have mutiple instances
std::unordered_map<SCH_SHEET*, PANEL_SYNC_SHEET_PINS*> m_panels;
PlaceItemKind m_placeItemKind;
EDA_ITEM* m_placementTemplate;
EDA_ITEM* m_currentTemplate;
std::set<EDA_ITEM*> m_placementTemplateSet;
};
#endif

View File

@ -174,35 +174,43 @@ void PANEL_SYNC_SHEET_PINS::OnBtnAddLabelsClicked( wxCommandEvent& aEvent )
{
WXUNUSED( aEvent )
if( auto idx = m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSelectedIndex();
idx.has_value() )
wxDataViewItemArray selected_items;
std::set<EDA_ITEM*> selected_items_set;
m_viewSheetPins->GetSelections( selected_items );
for( const auto& it : selected_items )
{
if( SHEET_SYNCHRONIZATION_ITE_PTR item =
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem(
*idx ) )
{
m_agent.PlaceHieraLable( m_sheet, m_path,
static_cast<SCH_SHEET_PIN*>( item->GetItem() ) );
}
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem( it ) )
selected_items_set.insert( item->GetItem() );
}
if( selected_items_set.empty() )
return;
m_agent.PlaceHieraLable( m_sheet, m_path, std::move( selected_items_set ) );
}
void PANEL_SYNC_SHEET_PINS::OnBtnAddSheetPinsClicked( wxCommandEvent& aEvent )
{
WXUNUSED( aEvent )
wxDataViewItemArray selected_items;
std::set<EDA_ITEM*> selected_items_set;
m_viewSheetLabels->GetSelections( selected_items );
if( auto idx = m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSelectedIndex();
idx.has_value() )
for( const auto& it : selected_items )
{
if( SHEET_SYNCHRONIZATION_ITE_PTR item =
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSynchronizationItem(
*idx ) )
{
m_agent.PlaceSheetPin( m_sheet, m_path,
static_cast<SCH_HIERLABEL*>( item->GetItem() ) );
}
it ) )
selected_items_set.insert( item->GetItem() );
}
if( selected_items_set.empty() )
return;
m_agent.PlaceSheetPin( m_sheet, m_path, std::move( selected_items_set ) );
}

View File

@ -111,16 +111,16 @@ void SHEET_SYNCHRONIZATION_AGENT::RemoveItem( SHEET_SYNCHRONIZATION_ITEM& aItem,
void SHEET_SYNCHRONIZATION_AGENT::PlaceSheetPin( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath,
SCH_HIERLABEL* aLabel )
std::set<EDA_ITEM*> const& aLabels )
{
SCH_SHEET_PATH cp = aPath;
cp.pop_back();
m_doPlaceItem( aSheet, cp, SHEET_SYNCHRONIZATION_PLACEMENT::PLACE_SHEET_PIN, aLabel );
m_doPlaceItem( aSheet, cp, SHEET_SYNCHRONIZATION_PLACEMENT::PLACE_SHEET_PIN, aLabels );
}
void SHEET_SYNCHRONIZATION_AGENT::PlaceHieraLable( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath,
SCH_SHEET_PIN* aPin )
std::set<EDA_ITEM*> const& aPins )
{
m_doPlaceItem( aSheet, aPath, SHEET_SYNCHRONIZATION_PLACEMENT::PLACE_HIERLABEL, aPin );
m_doPlaceItem( aSheet, aPath, SHEET_SYNCHRONIZATION_PLACEMENT::PLACE_HIERLABEL, aPins );
}

View File

@ -58,8 +58,9 @@ public:
using DO_MODIFY_ITEM = std::function<void( EDA_ITEM*, SCH_SHEET_PATH, MODIFICATION const& )>;
using DO_PLACE_ITEM = std::function<void( SCH_SHEET*, SCH_SHEET_PATH,
SHEET_SYNCHRONIZATION_PLACEMENT, EDA_ITEM* )>;
using DO_PLACE_ITEM =
std::function<void( SCH_SHEET*, SCH_SHEET_PATH, SHEET_SYNCHRONIZATION_PLACEMENT,
std::set<EDA_ITEM*> const& )>;
SHEET_SYNCHRONIZATION_AGENT( DO_MODIFY_ITEM aDoModify, DO_DELETE_ITEM aDoDelete,
@ -76,9 +77,11 @@ public:
void RemoveItem( SHEET_SYNCHRONIZATION_ITEM& aItem, SCH_SHEET* aSheet,
SCH_SHEET_PATH const& aPath );
void PlaceSheetPin( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath, SCH_HIERLABEL* aLabel );
void PlaceSheetPin( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath,
std::set<EDA_ITEM*> const& aLabels );
void PlaceHieraLable( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath, SCH_SHEET_PIN* aPin );
void PlaceHieraLable( SCH_SHEET* aSheet, SCH_SHEET_PATH const& aPath,
std::set<EDA_ITEM*> const& aPins );
private:

View File

@ -183,6 +183,13 @@ SHEET_SYNCHRONIZATION_MODEL::GetSynchronizationItem( unsigned aIndex ) const
}
SHEET_SYNCHRONIZATION_ITE_PTR
SHEET_SYNCHRONIZATION_MODEL::GetSynchronizationItem( wxDataViewItem const& aItem ) const
{
return GetSynchronizationItem( GetRow( aItem ) );
}
void SHEET_SYNCHRONIZATION_MODEL::OnRowSelected( std::optional<unsigned> aRow )
{
m_selectedIndex = aRow;

View File

@ -98,6 +98,8 @@ public:
SHEET_SYNCHRONIZATION_ITE_PTR GetSynchronizationItem( unsigned aIndex ) const;
SHEET_SYNCHRONIZATION_ITE_PTR GetSynchronizationItem( wxDataViewItem const& aItem ) const;
void OnRowSelected( std::optional<unsigned> aRow );
void UpdateItems( SHEET_SYNCHRONIZATION_ITEM_LIST aItems );

View File

@ -1915,6 +1915,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
{
PLACE_NEXT:
// First click creates...
if( !item )
{
@ -2083,9 +2084,16 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
{
m_dialogSyncSheetPin->EndPlaceItem( item );
if( m_dialogSyncSheetPin->CanPlaceMore() )
{
item = nullptr;
goto PLACE_NEXT;
}
m_frame->PopTool( aEvent );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
m_dialogSyncSheetPin->EndPlaceItem( item );
m_dialogSyncSheetPin->Show( true );
break;
}
@ -2182,9 +2190,9 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
controls->ForceCursorPosition( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->GetPlacementTemplate() )
if( m_dialogSyncSheetPin && m_dialogSyncSheetPin->CanPlaceMore() )
{
m_dialogSyncSheetPin->EndPlaceItem( nullptr );
m_dialogSyncSheetPin->EndPlacement();
m_dialogSyncSheetPin->Show( true );
}
@ -3221,7 +3229,7 @@ int SCH_DRAWING_TOOLS::doSyncSheetsPins( std::list<SCH_SHEET_PATH> sheetPaths )
},
[&]( SCH_SHEET* aItem, SCH_SHEET_PATH aPath,
SHEET_SYNCHRONIZATION_AGENT::SHEET_SYNCHRONIZATION_PLACEMENT aOp,
EDA_ITEM* aTemplate )
std::set<EDA_ITEM*> aTemplates )
{
switch( aOp )
{
@ -3229,9 +3237,9 @@ int SCH_DRAWING_TOOLS::doSyncSheetsPins( std::list<SCH_SHEET_PATH> sheetPaths )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
m_dialogSyncSheetPin->Hide();
m_dialogSyncSheetPin->BeginPlaceItem(
m_dialogSyncSheetPin->PreparePlacementTemplate(
sheet, DIALOG_SYNC_SHEET_PINS::PlaceItemKind::HIERLABEL,
aTemplate );
aTemplates );
m_frame->GetToolManager()->RunAction<SCH_SHEET_PATH*>(
EE_ACTIONS::changeSheet, &aPath );
m_toolMgr->RunAction( EE_ACTIONS::placeHierLabel );
@ -3241,9 +3249,9 @@ int SCH_DRAWING_TOOLS::doSyncSheetsPins( std::list<SCH_SHEET_PATH> sheetPaths )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
m_dialogSyncSheetPin->Hide();
m_dialogSyncSheetPin->BeginPlaceItem(
m_dialogSyncSheetPin->PreparePlacementTemplate(
sheet, DIALOG_SYNC_SHEET_PINS::PlaceItemKind::SHEET_PIN,
aTemplate );
aTemplates );
m_frame->GetToolManager()->RunAction<SCH_SHEET_PATH*>(
EE_ACTIONS::changeSheet, &aPath );
m_toolMgr->GetTool<EE_SELECTION_TOOL>()->SyncSelection( {}, nullptr,