391 lines
13 KiB
C++
391 lines
13 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
|
|
* Copyright (C) 2023 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 2
|
|
* 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, you may find one here:
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "panel_sync_sheet_pins.h"
|
|
#include "sch_sheet_pin.h"
|
|
#include "sheet_synchronization_model.h"
|
|
#include "sheet_synchronization_item.h"
|
|
#include "sync_sheet_pin_preference.h"
|
|
#include "sheet_synchronization_agent.h"
|
|
|
|
#include <bitmaps.h>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <sch_label.h>
|
|
#include <sch_sheet.h>
|
|
#include <sch_pin.h>
|
|
#include <sch_screen.h>
|
|
#include <wx/bookctrl.h>
|
|
#include <eda_item.h>
|
|
|
|
PANEL_SYNC_SHEET_PINS::PANEL_SYNC_SHEET_PINS( wxWindow* aParent, SCH_SHEET* aSheet,
|
|
wxNotebook* aNoteBook, int aIndex,
|
|
SHEET_SYNCHRONIZATION_AGENT& aAgent,
|
|
const SCH_SHEET_PATH& aPath ) :
|
|
PANEL_SYNC_SHEET_PINS_BASE( aParent ),
|
|
m_sheet( aSheet ),
|
|
m_noteBook( aNoteBook ),
|
|
m_index( aIndex ),
|
|
m_sheetFileName( aSheet->GetFileName() ),
|
|
m_agent( aAgent ),
|
|
m_path( std::move( aPath ) )
|
|
{
|
|
m_btnUsePinAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierar_pin ) );
|
|
m_btnUseLabelAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierarchical_label ) );
|
|
m_btnUndo->SetBitmap( KiBitmapBundle( BITMAPS::left ) );
|
|
|
|
m_labelSheetName->SetLabel( aSheet->GetFileName() );
|
|
m_labelSymName->SetLabel( aSheet->GetShownName( true ) );
|
|
|
|
|
|
for( wxDataViewCtrl* view : { m_viewAssociated, m_viewSheetLabels, m_viewSheetPins } )
|
|
{
|
|
for( int col : { SHEET_SYNCHRONIZATION_MODEL::NAME, SHEET_SYNCHRONIZATION_MODEL::SHAPE } )
|
|
{
|
|
switch( col )
|
|
{
|
|
case SHEET_SYNCHRONIZATION_MODEL::NAME:
|
|
view->AppendIconTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col );
|
|
break;
|
|
case SHEET_SYNCHRONIZATION_MODEL::SHAPE:
|
|
view->AppendTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::map<int, wxDataViewCtrl*> view_idx = std::map<int, wxDataViewCtrl*>{
|
|
{ SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL, m_viewSheetLabels },
|
|
{ SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN, m_viewSheetPins },
|
|
{ SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED, m_viewAssociated },
|
|
};
|
|
|
|
for( auto& [idx, view] : view_idx )
|
|
{
|
|
auto model = wxObjectDataPtr<SHEET_SYNCHRONIZATION_MODEL>(
|
|
new SHEET_SYNCHRONIZATION_MODEL( m_agent, m_sheet, m_path ) );
|
|
view->AssociateModel( model.get() );
|
|
m_models.try_emplace( idx, std::move( model ) );
|
|
}
|
|
|
|
for( auto& [idx, view] : view_idx )
|
|
PostProcessModelSelection( idx, {} );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::UpdateForms()
|
|
{
|
|
SHEET_SYNCHRONIZATION_ITEM_LIST labels_list, pins_list, associated_list;
|
|
auto labels_ori = m_sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T );
|
|
std::vector<SCH_SHEET_PIN*> pins_ori = m_sheet->GetPins();
|
|
|
|
auto check_matched = [&]( SCH_HIERLABEL* label )
|
|
{
|
|
for( size_t i = 0; i < pins_ori.size(); i++ )
|
|
{
|
|
SCH_SHEET_PIN* cur_pin = pins_ori[i];
|
|
|
|
if( label->GetText() == cur_pin->GetText() && label->GetShape() == cur_pin->GetShape() )
|
|
{
|
|
associated_list.push_back(
|
|
std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label, cur_pin ) );
|
|
pins_ori.erase( pins_ori.begin() + i );
|
|
return;
|
|
}
|
|
}
|
|
|
|
labels_list.push_back(
|
|
std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( label, m_sheet ) );
|
|
};
|
|
|
|
for( const auto& item : labels_ori )
|
|
check_matched( static_cast<SCH_HIERLABEL*>( item ) );
|
|
|
|
for( const auto& pin : pins_ori )
|
|
pins_list.push_back( std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>(
|
|
static_cast<SCH_SHEET_PIN*>( pin ), m_sheet ) );
|
|
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->UpdateItems( std::move( labels_list ) );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->UpdateItems( std::move( pins_list ) );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->UpdateItems( std::move( associated_list ) );
|
|
|
|
UpdatePageImage();
|
|
}
|
|
|
|
|
|
SHEET_SYNCHRONIZATION_MODEL_PTR PANEL_SYNC_SHEET_PINS::GetModel( int aKind ) const
|
|
{
|
|
return m_models.at( aKind );
|
|
}
|
|
|
|
|
|
const wxString& PANEL_SYNC_SHEET_PINS::GetSheetFileName() const
|
|
{
|
|
return m_sheetFileName;
|
|
}
|
|
|
|
|
|
PANEL_SYNC_SHEET_PINS::~PANEL_SYNC_SHEET_PINS()
|
|
{
|
|
}
|
|
|
|
|
|
bool PANEL_SYNC_SHEET_PINS::HasUndefinedSheetPing() const
|
|
{
|
|
return !m_models.at( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL )->GetCount()
|
|
&& !m_models.at( SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN )->GetCount();
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnAddLabelsClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
|
|
if( auto idx = m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSelectedIndex();
|
|
idx.has_value() )
|
|
{
|
|
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() ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnAddSheetPinsClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
|
|
if( auto idx = m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSelectedIndex();
|
|
idx.has_value() )
|
|
{
|
|
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() ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::GenericSync( SYNC_DIRECTION direction )
|
|
{
|
|
wxDataViewItem labelIdx = m_viewSheetLabels->GetSelection();
|
|
wxDataViewItem pinIdx = m_viewSheetPins->GetSelection();
|
|
|
|
for( auto& idx : { labelIdx, pinIdx } )
|
|
{
|
|
if( !idx.IsOk() )
|
|
return;
|
|
}
|
|
|
|
SHEET_SYNCHRONIZATION_ITE_PTR labelItem =
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->TakeItem( labelIdx );
|
|
SHEET_SYNCHRONIZATION_ITE_PTR pinItem =
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->TakeItem( pinIdx );
|
|
|
|
for( const auto& item : { labelItem, pinItem } )
|
|
{
|
|
if( !item )
|
|
return;
|
|
}
|
|
|
|
auto label_ptr =
|
|
std::static_pointer_cast<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( labelItem )->GetLabel();
|
|
auto pin_ptr =
|
|
std::static_pointer_cast<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( pinItem )->GetPin();
|
|
|
|
switch( direction )
|
|
{
|
|
case SYNC_DIRECTION::USE_LABEL_AS_TEMPLATE:
|
|
m_agent.ModifyItem(
|
|
*pinItem,
|
|
[&]()
|
|
{
|
|
pin_ptr->SetText( label_ptr->GetText() );
|
|
pin_ptr->SetShape( label_ptr->GetShape() );
|
|
},
|
|
m_path );
|
|
break;
|
|
case SYNC_DIRECTION::USE_PIN_AS_TEMPLATE:
|
|
m_agent.ModifyItem(
|
|
*labelItem,
|
|
[&]()
|
|
{
|
|
label_ptr->SetText( pin_ptr->GetText() );
|
|
label_ptr->SetShape( pin_ptr->GetShape() );
|
|
},
|
|
m_path );
|
|
break;
|
|
}
|
|
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->AppendItem(
|
|
std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label_ptr, pin_ptr ) );
|
|
UpdatePageImage();
|
|
|
|
for( auto idx :
|
|
{ SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL, SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN } )
|
|
{
|
|
PostProcessModelSelection( idx, {} );
|
|
}
|
|
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->DoNotify();
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::UpdatePageImage() const
|
|
{
|
|
m_noteBook->SetPageImage( m_index, HasUndefinedSheetPing()
|
|
? SYNC_SHEET_PIN_PREFERENCE::HAS_UNMATCHED
|
|
: SYNC_SHEET_PIN_PREFERENCE::ALL_MATCHED );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnUsePinAsTemplateClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
return GenericSync( SYNC_DIRECTION::USE_PIN_AS_TEMPLATE );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnUseLabelAsTemplateClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
return GenericSync( SYNC_DIRECTION::USE_LABEL_AS_TEMPLATE );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnRmPinsClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
wxDataViewItemArray array;
|
|
m_viewSheetPins->GetSelections( array );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->RemoveItems( array );
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN, {} );
|
|
UpdatePageImage();
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnRmLabelsClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
wxDataViewItemArray array;
|
|
m_viewSheetLabels->GetSelections( array );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->RemoveItems( array );
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL, {} );
|
|
UpdatePageImage();
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnBtnUndoClicked( wxCommandEvent& aEvent )
|
|
{
|
|
WXUNUSED( aEvent )
|
|
wxDataViewItemArray indexes;
|
|
m_viewAssociated->GetSelections( indexes );
|
|
auto items = m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->TakeItems( indexes );
|
|
|
|
if( !items.size() )
|
|
return;
|
|
|
|
for( auto& item : items )
|
|
{
|
|
auto associated = std::static_pointer_cast<ASSOCIATED_SCH_LABEL_PIN>( item );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->AppendItem(
|
|
std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( associated->GetLabel(),
|
|
m_sheet ) );
|
|
m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->AppendItem(
|
|
std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( associated->GetPin(),
|
|
m_sheet ) );
|
|
}
|
|
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED, {} );
|
|
UpdatePageImage();
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::PostProcessModelSelection( int aIdex, wxDataViewItem const& aItem )
|
|
{
|
|
if( aItem.IsOk() )
|
|
m_models[aIdex]->OnRowSelected( m_models[aIdex]->GetRow( aItem ) );
|
|
else
|
|
m_models[aIdex]->OnRowSelected( {} );
|
|
|
|
switch( aIdex )
|
|
{
|
|
case SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN:
|
|
{
|
|
for( auto btn : { m_btnAddLabels, m_btnRmPins } )
|
|
btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex() );
|
|
|
|
break;
|
|
}
|
|
case SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL:
|
|
{
|
|
for( auto btn : { m_btnAddSheetPins, m_btnRmLabels } )
|
|
btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
|
|
|
|
break;
|
|
}
|
|
case SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED:
|
|
{
|
|
m_btnUndo->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->HasSelectedIndex() );
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if( aIdex != SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED )
|
|
{
|
|
for( auto btn : { m_btnUsePinAsTemplate, m_btnUseLabelAsTemplate } )
|
|
{
|
|
btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex()
|
|
&& m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnViewSheetLabelCellClicked( wxDataViewEvent& aEvent )
|
|
{
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL, aEvent.GetItem() );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnViewSheetPinCellClicked( wxDataViewEvent& aEvent )
|
|
{
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN, aEvent.GetItem() );
|
|
}
|
|
|
|
|
|
void PANEL_SYNC_SHEET_PINS::OnViewMatchedCellClicked( wxDataViewEvent& aEvent )
|
|
{
|
|
PostProcessModelSelection( SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED, aEvent.GetItem() );
|
|
}
|