195 lines
7.1 KiB
C++
195 lines
7.1 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 "dialog_sync_sheet_pins.h"
|
|
#include "panel_sync_sheet_pins.h"
|
|
#include "sch_item.h"
|
|
#include "sch_label.h"
|
|
#include "sheet_synchronization_model.h"
|
|
#include "sync_sheet_pin_preference.h"
|
|
#include "sheet_synchronization_notifier.h"
|
|
#include "sheet_synchronization_agent.h"
|
|
#include "sheet_synchronization_item.h"
|
|
|
|
#include <memory>
|
|
#include <cstddef>
|
|
#include <sch_sheet_pin.h>
|
|
#include <sch_sheet.h>
|
|
#include <unordered_map>
|
|
#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 )
|
|
{
|
|
wxImageList* imageList = new wxImageList( SYNC_SHEET_PIN_PREFERENCE::NORMAL_WIDTH,
|
|
SYNC_SHEET_PIN_PREFERENCE::NORMAL_HEIGHT );
|
|
|
|
for( const auto [icon_idx, bitmap] : SYNC_SHEET_PIN_PREFERENCE::GetBookctrlPageIcon() )
|
|
{
|
|
imageList->Add( KiBitmap( bitmap, SYNC_SHEET_PIN_PREFERENCE::NORMAL_HEIGHT ) );
|
|
}
|
|
|
|
m_notebook->AssignImageList( imageList );
|
|
int count = -1;
|
|
std::unordered_map<wxString, std::list<PANEL_SYNC_SHEET_PINS*>> sheet_instances;
|
|
|
|
for( const auto& sheet_path : aSheetPath )
|
|
{
|
|
auto sheet = sheet_path.Last();
|
|
wxString fileName = sheet->GetFileName();
|
|
PANEL_SYNC_SHEET_PINS* page = new PANEL_SYNC_SHEET_PINS( m_notebook, sheet, m_notebook,
|
|
++count, *m_agent, sheet_path );
|
|
m_notebook->AddPage( page, sheet->GetShownName( true ), {}, page->HasUndefinedSheetPing() );
|
|
page->UpdateForms();
|
|
|
|
if( sheet_instances.find( fileName ) == sheet_instances.end() )
|
|
{
|
|
sheet_instances.try_emplace( fileName, std::list<PANEL_SYNC_SHEET_PINS*>{ page } );
|
|
}
|
|
else
|
|
{
|
|
sheet_instances[fileName].push_back( page );
|
|
}
|
|
|
|
m_panels.try_emplace( sheet, page );
|
|
}
|
|
|
|
for( auto& [sheet_name, panel_list] : sheet_instances )
|
|
{
|
|
if( panel_list.size() > 1 )
|
|
{
|
|
std::list<std::shared_ptr<SHEET_SYNCHRONIZATION_NOTIFIER>> sheet_change_notifiers;
|
|
std::list<SHEET_SYNCHRONIZATION_MODEL*> sheet_sync_models;
|
|
|
|
for( auto& panel : panel_list )
|
|
{
|
|
SHEET_SYNCHRONIZATION_MODEL* model =
|
|
panel->GetModel( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL ).get();
|
|
sheet_sync_models.push_back( model );
|
|
sheet_change_notifiers.push_back(
|
|
std::make_shared<SHEET_FILE_CHANGE_NOTIFIER>( model, panel ) );
|
|
}
|
|
|
|
for( auto& notifier : sheet_change_notifiers )
|
|
{
|
|
for( auto& other : sheet_sync_models )
|
|
{
|
|
if( notifier->GetOwner() != other )
|
|
{
|
|
other->AddNotifier( notifier );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_sizerMain->Layout();
|
|
m_sizerMain->Fit( this );
|
|
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SYNC_SHEET_PINS::OnClose, this );
|
|
}
|
|
|
|
|
|
DIALOG_SYNC_SHEET_PINS::~DIALOG_SYNC_SHEET_PINS() = default;
|
|
|
|
|
|
void DIALOG_SYNC_SHEET_PINS::OnCloseBtnClick( wxCommandEvent& event )
|
|
{
|
|
Close();
|
|
}
|
|
|
|
|
|
void DIALOG_SYNC_SHEET_PINS::OnClose( wxCloseEvent& aEvent )
|
|
{
|
|
aEvent.Skip();
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
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 new_item = static_cast<SCH_HIERLABEL*>( aNewItem );
|
|
|
|
//Usr may edit the name or shape while placing the new item , do sync if either differs
|
|
if( template_item->GetText() != new_item->GetText()
|
|
|| template_item->GetShape() != new_item->GetShape() )
|
|
{
|
|
m_agent->ModifyItem(
|
|
template_item,
|
|
[&]()
|
|
{
|
|
template_item->SetText( new_item->GetText() );
|
|
template_item->SetShape( new_item->GetShape() );
|
|
},
|
|
panel->GetSheetPath(),
|
|
PlaceItemKind::SHEET_PIN == m_placeItemKind
|
|
? SHEET_SYNCHRONIZATION_ITEM_KIND::HIERLABEL
|
|
: SHEET_SYNCHRONIZATION_ITEM_KIND::SHEET_PIN );
|
|
}
|
|
|
|
panel->UpdateForms();
|
|
|
|
if( PlaceItemKind::HIERLABEL == m_placeItemKind )
|
|
panel->GetModel( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL )->DoNotify();
|
|
}
|
|
}
|
|
|
|
|
|
void DIALOG_SYNC_SHEET_PINS::BeginPlaceItem( SCH_SHEET* aSheet, PlaceItemKind aKind,
|
|
EDA_ITEM* aTemplate )
|
|
{
|
|
m_lastEditSheet = aSheet;
|
|
m_placeItemKind = aKind;
|
|
m_placementTemplate = aTemplate;
|
|
}
|
|
|
|
|
|
SCH_HIERLABEL* DIALOG_SYNC_SHEET_PINS::GetPlacementTemplate() const
|
|
{
|
|
if( !m_placementTemplate )
|
|
return {};
|
|
|
|
return static_cast<SCH_HIERLABEL*>( m_placementTemplate );
|
|
}
|