KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_sync_sheet_pins.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Ethan Chien <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26#include "sch_sheet_pin.h"
31
32#include <bitmaps.h>
33#include <map>
34#include <memory>
35#include <sch_label.h>
36#include <sch_sheet.h>
37#include <sch_pin.h>
38#include <sch_screen.h>
39#include <wx/bookctrl.h>
40#include <eda_item.h>
41#include <wx/string.h>
42#include <string_utils.h>
43
44// sch_label.cpp
45extern wxString getElectricalTypeLabel( LABEL_FLAG_SHAPE aType );
46
48 wxNotebook* aNoteBook, int aIndex,
50 const SCH_SHEET_PATH& aPath ) :
51 PANEL_SYNC_SHEET_PINS_BASE( aParent ), m_sheet( aSheet ), m_noteBook( aNoteBook ),
52 m_index( aIndex ), m_sheetFileName( aSheet->GetFileName() ), m_agent( aAgent ),
53 m_path( std::move( aPath ) ),
54 m_views( {
58 } )
59{
60 m_btnUsePinAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierar_pin ) );
61 m_btnUseLabelAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierarchical_label ) );
62 m_btnUndo->SetBitmap( KiBitmapBundle( BITMAPS::left ) );
63
64 m_labelSheetName->SetLabel( aSheet->GetFileName() );
65 m_labelSymName->SetLabel( aSheet->GetShownName( true ) );
66
67
68 for( auto& [idx, view] : m_views )
69 {
70 auto model = wxObjectDataPtr<SHEET_SYNCHRONIZATION_MODEL>(
71 new SHEET_SYNCHRONIZATION_MODEL( m_agent, m_sheet, m_path ) );
72 view->AssociateModel( model.get() );
73 m_models.try_emplace( idx, std::move( model ) );
74
76 {
77 switch( col )
78 {
80 view->AppendIconTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
81 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
82 break;
84 view->AppendTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
85 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
86 break;
87 }
88 }
89 }
90
91 for( auto& [idx, view] : m_views )
92 PostProcessModelSelection( idx, {} );
93}
94
95
97{
98 SHEET_SYNCHRONIZATION_ITEM_LIST labels_list, pins_list, associated_list;
99 auto labels_ori = m_sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T );
100 std::vector<SCH_SHEET_PIN*> pins_ori = m_sheet->GetPins();
101
102 // De-duplicate the hierarchical labels list
103 std::set<wxString> dedup_labels_ori_text;
104 std::vector<SCH_HIERLABEL*> dedup_labels_ori;
105
106 for( const auto& item : labels_ori )
107 {
108 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
109
110 if( dedup_labels_ori_text.count( label->GetText() ) == 0 )
111 {
112 dedup_labels_ori_text.insert( label->GetText() );
113 dedup_labels_ori.push_back( label );
114 }
115 }
116
117 std::sort( dedup_labels_ori.begin(), dedup_labels_ori.end(),
118 []( const SCH_HIERLABEL* label1, const SCH_HIERLABEL* label2 )
119 {
120 return StrNumCmp( label1->GetText(), label2->GetText(), true ) < 0;
121 } );
122
123 auto check_matched = [&]( SCH_HIERLABEL* label )
124 {
125 for( size_t i = 0; i < pins_ori.size(); i++ )
126 {
127 SCH_SHEET_PIN* cur_pin = pins_ori[i];
128
129 if( label->GetText() == cur_pin->GetText() && label->GetShape() == cur_pin->GetShape() )
130 {
131 associated_list.push_back(
132 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label, cur_pin ) );
133 pins_ori.erase( pins_ori.begin() + i );
134 return;
135 }
136 }
137
138 labels_list.push_back(
139 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( label, m_sheet ) );
140 };
141
142 for( const auto& item : dedup_labels_ori )
143 check_matched( static_cast<SCH_HIERLABEL*>( item ) );
144
145 for( const auto& pin : pins_ori )
146 pins_list.push_back( std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>(
147 static_cast<SCH_SHEET_PIN*>( pin ), m_sheet ) );
148
149 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->UpdateItems( std::move( labels_list ) );
150 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->UpdateItems( std::move( pins_list ) );
151 m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->UpdateItems( std::move( associated_list ) );
152
154}
155
156
158{
159 return m_models.at( aKind );
160}
161
162
164{
165 return m_sheetFileName;
166}
167
168
170{
171}
172
173
175{
176 return !m_models.at( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL )->GetCount()
178}
179
180
182{
183 WXUNUSED( aEvent )
184
185 wxDataViewItemArray selected_items;
186 std::set<EDA_ITEM*> selected_items_set;
187 m_viewSheetPins->GetSelections( selected_items );
188
189 for( const auto& it : selected_items )
190 {
192 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem( it ) )
193 selected_items_set.insert( item->GetItem() );
194 }
195
196 if( selected_items_set.empty() )
197 return;
198
199 m_agent.PlaceHieraLable( m_sheet, m_path, std::move( selected_items_set ) );
200}
201
202
204{
205 WXUNUSED( aEvent )
206 wxDataViewItemArray selected_items;
207 std::set<EDA_ITEM*> selected_items_set;
208 m_viewSheetLabels->GetSelections( selected_items );
209
210 for( const auto& it : selected_items )
211 {
213 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSynchronizationItem(
214 it ) )
215 selected_items_set.insert( item->GetItem() );
216 }
217
218 if( selected_items_set.empty() )
219 return;
220
221 m_agent.PlaceSheetPin( m_sheet, m_path, std::move( selected_items_set ) );
222}
223
224
226{
227 wxDataViewItem labelIdx = m_viewSheetLabels->GetSelection();
228 wxDataViewItem pinIdx = m_viewSheetPins->GetSelection();
229
230 for( auto& idx : { labelIdx, pinIdx } )
231 {
232 if( !idx.IsOk() )
233 return;
234 }
235
240
241 for( const auto& item : { labelItem, pinItem } )
242 {
243 if( !item )
244 return;
245 }
246
247 auto label_ptr =
248 std::static_pointer_cast<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( labelItem )->GetLabel();
249 auto pin_ptr =
250 std::static_pointer_cast<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( pinItem )->GetPin();
251
252 switch( direction )
253 {
256 *pinItem,
257 [&]()
258 {
259 pin_ptr->SetText( label_ptr->GetText() );
260 pin_ptr->SetShape( label_ptr->GetShape() );
261 },
262 m_path );
263 break;
266 *labelItem,
267 [&]()
268 {
269 label_ptr->SetText( pin_ptr->GetText() );
270 label_ptr->SetShape( pin_ptr->GetShape() );
271 },
272 m_path );
273 break;
274 }
275
277 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label_ptr, pin_ptr ) );
279
280 for( auto idx :
282 {
283 PostProcessModelSelection( idx, {} );
284 }
285
287}
288
289
291{
295}
296
297
299{
300 WXUNUSED( aEvent )
302}
303
304
306{
307 WXUNUSED( aEvent )
309}
310
311
312void PANEL_SYNC_SHEET_PINS::OnBtnRmPinsClicked( wxCommandEvent& aEvent )
313{
314 WXUNUSED( aEvent )
315 wxDataViewItemArray array;
316 m_viewSheetPins->GetSelections( array );
320}
321
322
324{
325 WXUNUSED( aEvent )
326 wxDataViewItemArray array;
327 m_viewSheetLabels->GetSelections( array );
331}
332
333
334void PANEL_SYNC_SHEET_PINS::OnBtnUndoClicked( wxCommandEvent& aEvent )
335{
336 WXUNUSED( aEvent )
337 wxDataViewItemArray indexes;
338 m_viewAssociated->GetSelections( indexes );
339 auto items = m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->TakeItems( indexes );
340
341 if( !items.size() )
342 return;
343
344 for( auto& item : items )
345 {
346 auto associated = std::static_pointer_cast<ASSOCIATED_SCH_LABEL_PIN>( item );
348 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( associated->GetLabel(),
349 m_sheet ) );
351 std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( associated->GetPin(),
352 m_sheet ) );
353 }
354
357}
358
359
360void PANEL_SYNC_SHEET_PINS::PostProcessModelSelection( int aIdex, wxDataViewItem const& aItem )
361{
362 if( aItem.IsOk() )
363 m_models[aIdex]->OnRowSelected( m_models[aIdex]->GetRow( aItem ) );
364 else
365 m_models[aIdex]->OnRowSelected( {} );
366
367 const bool has_selected_row = m_views[aIdex]->GetSelectedItemsCount() > 0;
368
369 switch( aIdex )
370 {
372 {
373 for( auto btn : { m_btnAddLabels, m_btnRmPins } )
374 btn->Enable( has_selected_row );
375
376 break;
377 }
379 {
380 for( auto btn : { m_btnAddSheetPins, m_btnRmLabels } )
381 btn->Enable( has_selected_row );
382
383 break;
384 }
386 {
387 m_btnUndo->Enable( has_selected_row );
388 break;
389 }
390 default:
391 break;
392 }
393
395 {
397 {
398 btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex()
399 && m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
400 }
401 }
402}
403
404
406{
408}
409
410
412{
414}
415
416
418{
420}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
@ add_hierarchical_label
@ add_hierar_pin
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
Class PANEL_SYNC_SHEET_PINS_BASE.
SHEET_SYNCHRONIZATION_MODEL_PTR GetModel(int aKind) const
void PostProcessModelSelection(int aIdex, wxDataViewItem const &aItem)
void OnBtnUsePinAsTemplateClicked(wxCommandEvent &event) override
void OnBtnRmPinsClicked(wxCommandEvent &event) override
void GenericSync(SYNC_DIRECTION direction)
void OnBtnAddLabelsClicked(wxCommandEvent &event) override
void OnViewSheetLabelCellClicked(wxDataViewEvent &event) override
void OnViewMatchedCellClicked(wxDataViewEvent &event) override
const wxString & GetSheetFileName() const
SYNC_SHEET_PINT_VIEWS m_views
void OnBtnUseLabelAsTemplateClicked(wxCommandEvent &event) override
void OnBtnRmLabelsClicked(wxCommandEvent &event) override
void OnBtnAddSheetPinsClicked(wxCommandEvent &event) override
void OnBtnUndoClicked(wxCommandEvent &event) override
SHEET_SYNCHRONIZATION_AGENT & m_agent
PANEL_SYNC_SHEET_PINS(wxWindow *aParent, SCH_SHEET *aSheet, wxNotebook *aNoteBook, int aIndex, SHEET_SYNCHRONIZATION_AGENT &aAgent, const SCH_SHEET_PATH &aPath)
void OnViewSheetPinCellClicked(wxDataViewEvent &event) override
SYNC_SHEET_PINT_MODELS m_models
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:188
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:59
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:111
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:182
Agent for all the modifications while syncing the sheet pin and hierarchical label.
void PlaceHieraLable(SCH_SHEET *aSheet, SCH_SHEET_PATH const &aPath, std::set< EDA_ITEM * > const &aPins)
void PlaceSheetPin(SCH_SHEET *aSheet, SCH_SHEET_PATH const &aPath, std::set< EDA_ITEM * > const &aLabels)
void ModifyItem(SHEET_SYNCHRONIZATION_ITEM &aItem, std::function< void()> const &aDoModify, const SCH_SHEET_PATH &aPath)
STL namespace.
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition: sch_label.cpp:93
wxObjectDataPtr< SHEET_SYNCHRONIZATION_MODEL > SHEET_SYNCHRONIZATION_MODEL_PTR
LABEL_FLAG_SHAPE
Definition: sch_label.h:98
std::vector< SHEET_SYNCHRONIZATION_ITE_PTR > SHEET_SYNCHRONIZATION_ITEM_LIST
std::shared_ptr< SHEET_SYNCHRONIZATION_ITEM > SHEET_SYNCHRONIZATION_ITE_PTR
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169