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
47PANEL_SYNC_SHEET_PINS::PANEL_SYNC_SHEET_PINS( wxWindow* aParent, SCH_SHEET* aSheet, wxNotebook* aNoteBook,
48 int aIndex, SHEET_SYNCHRONIZATION_AGENT& aAgent,
49 const SCH_SHEET_PATH& aPath ) :
51 m_sheet( aSheet ),
52 m_noteBook( aNoteBook ),
53 m_index( aIndex ),
54 m_sheetFileName( aSheet->GetFileName() ),
55 m_agent( aAgent ),
56 m_path( aPath ),
57 m_views( {
61 } )
62{
63 m_btnUsePinAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierar_pin ) );
64 m_btnUseLabelAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierarchical_label ) );
65 m_btnUndo->SetBitmap( KiBitmapBundle( BITMAPS::left ) );
66
67 m_labelSheetName->SetLabel( aSheet->GetFileName() );
68 m_labelSymName->SetLabel( aSheet->GetShownName( true ) );
69
70
71 for( auto& [idx, view] : m_views )
72 {
73 auto model = wxObjectDataPtr<SHEET_SYNCHRONIZATION_MODEL>(
74 new SHEET_SYNCHRONIZATION_MODEL( m_agent, m_sheet, m_path ) );
75 view->AssociateModel( model.get() );
76 m_models.try_emplace( idx, std::move( model ) );
77
79 {
80 switch( col )
81 {
83 view->AppendIconTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
84 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
85 break;
87 view->AppendTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
88 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
89 break;
90 }
91 }
92 }
93
94 for( auto& [idx, view] : m_views )
95 PostProcessModelSelection( idx, {} );
96}
97
98
100{
101 SHEET_SYNCHRONIZATION_ITEM_LIST labels_list, pins_list, associated_list;
102 auto labels_ori = m_sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T );
103 std::vector<SCH_SHEET_PIN*> pins_ori = m_sheet->GetPins();
104
105 // De-duplicate the hierarchical labels list
106 std::set<wxString> dedup_labels_ori_text;
107 std::vector<SCH_HIERLABEL*> dedup_labels_ori;
108
109 for( const auto& item : labels_ori )
110 {
111 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
112
113 if( dedup_labels_ori_text.count( label->GetText() ) == 0 )
114 {
115 dedup_labels_ori_text.insert( label->GetText() );
116 dedup_labels_ori.push_back( label );
117 }
118 }
119
120 std::sort( dedup_labels_ori.begin(), dedup_labels_ori.end(),
121 []( const SCH_HIERLABEL* label1, const SCH_HIERLABEL* label2 )
122 {
123 return StrNumCmp( label1->GetText(), label2->GetText(), true ) < 0;
124 } );
125
126 auto check_matched = [&]( SCH_HIERLABEL* label )
127 {
128 for( size_t i = 0; i < pins_ori.size(); i++ )
129 {
130 SCH_SHEET_PIN* cur_pin = pins_ori[i];
131
132 if( label->GetText() == cur_pin->GetText() && label->GetShape() == cur_pin->GetShape() )
133 {
134 associated_list.push_back(
135 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label, cur_pin ) );
136 pins_ori.erase( pins_ori.begin() + i );
137 return;
138 }
139 }
140
141 labels_list.push_back(
142 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( label, m_sheet ) );
143 };
144
145 for( const auto& item : dedup_labels_ori )
146 check_matched( static_cast<SCH_HIERLABEL*>( item ) );
147
148 for( const auto& pin : pins_ori )
149 pins_list.push_back( std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>(
150 static_cast<SCH_SHEET_PIN*>( pin ), m_sheet ) );
151
152 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->UpdateItems( std::move( labels_list ) );
153 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->UpdateItems( std::move( pins_list ) );
154 m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->UpdateItems( std::move( associated_list ) );
155
157}
158
159
161{
162 return m_models.at( aKind );
163}
164
165
167{
168 return m_sheetFileName;
169}
170
171
173{
174}
175
176
178{
179 return !m_models.at( SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL )->GetCount()
181}
182
183
185{
186 WXUNUSED( aEvent )
187
188 wxDataViewItemArray selected_items;
189 std::set<EDA_ITEM*> selected_items_set;
190 m_viewSheetPins->GetSelections( selected_items );
191
192 for( const auto& it : selected_items )
193 {
195 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem( it ) )
196 selected_items_set.insert( item->GetItem() );
197 }
198
199 if( selected_items_set.empty() )
200 return;
201
202 m_agent.PlaceHieraLable( m_sheet, m_path, std::move( selected_items_set ) );
203}
204
205
207{
208 WXUNUSED( aEvent )
209 wxDataViewItemArray selected_items;
210 std::set<EDA_ITEM*> selected_items_set;
211 m_viewSheetLabels->GetSelections( selected_items );
212
213 for( const auto& it : selected_items )
214 {
216 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSynchronizationItem(
217 it ) )
218 selected_items_set.insert( item->GetItem() );
219 }
220
221 if( selected_items_set.empty() )
222 return;
223
224 m_agent.PlaceSheetPin( m_sheet, m_path, std::move( selected_items_set ) );
225}
226
227
229{
230 wxDataViewItem labelIdx = m_viewSheetLabels->GetSelection();
231 wxDataViewItem pinIdx = m_viewSheetPins->GetSelection();
232
233 for( auto& idx : { labelIdx, pinIdx } )
234 {
235 if( !idx.IsOk() )
236 return;
237 }
238
243
244 for( const auto& item : { labelItem, pinItem } )
245 {
246 if( !item )
247 return;
248 }
249
250 auto label_ptr =
251 std::static_pointer_cast<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( labelItem )->GetLabel();
252 auto pin_ptr =
253 std::static_pointer_cast<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( pinItem )->GetPin();
254
255 switch( direction )
256 {
259 *pinItem,
260 [&]()
261 {
262 pin_ptr->SetText( label_ptr->GetText() );
263 pin_ptr->SetShape( label_ptr->GetShape() );
264 },
265 m_path );
266 break;
269 *labelItem,
270 [&]()
271 {
272 label_ptr->SetText( pin_ptr->GetText() );
273 label_ptr->SetShape( pin_ptr->GetShape() );
274 },
275 m_path );
276 break;
277 }
278
280 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label_ptr, pin_ptr ) );
282
283 for( auto idx :
285 {
286 PostProcessModelSelection( idx, {} );
287 }
288
290}
291
292
294{
298}
299
300
302{
303 WXUNUSED( aEvent )
305}
306
307
309{
310 WXUNUSED( aEvent )
312}
313
314
315void PANEL_SYNC_SHEET_PINS::OnBtnRmPinsClicked( wxCommandEvent& aEvent )
316{
317 WXUNUSED( aEvent )
318 wxDataViewItemArray array;
319 m_viewSheetPins->GetSelections( array );
323}
324
325
327{
328 WXUNUSED( aEvent )
329 wxDataViewItemArray array;
330 m_viewSheetLabels->GetSelections( array );
334}
335
336
337void PANEL_SYNC_SHEET_PINS::OnBtnUndoClicked( wxCommandEvent& aEvent )
338{
339 WXUNUSED( aEvent )
340 wxDataViewItemArray indexes;
341 m_viewAssociated->GetSelections( indexes );
342 auto items = m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->TakeItems( indexes );
343
344 if( !items.size() )
345 return;
346
347 for( auto& item : items )
348 {
349 auto associated = std::static_pointer_cast<ASSOCIATED_SCH_LABEL_PIN>( item );
351 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( associated->GetLabel(),
352 m_sheet ) );
354 std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( associated->GetPin(),
355 m_sheet ) );
356 }
357
360}
361
362
363void PANEL_SYNC_SHEET_PINS::PostProcessModelSelection( int aIdex, wxDataViewItem const& aItem )
364{
365 if( aItem.IsOk() )
366 m_models[aIdex]->OnRowSelected( m_models[aIdex]->GetRow( aItem ) );
367 else
368 m_models[aIdex]->OnRowSelected( {} );
369
370 const bool has_selected_row = m_views[aIdex]->GetSelectedItemsCount() > 0;
371
372 switch( aIdex )
373 {
375 {
376 for( auto btn : { m_btnAddLabels, m_btnRmPins } )
377 btn->Enable( has_selected_row );
378
379 break;
380 }
382 {
383 for( auto btn : { m_btnAddSheetPins, m_btnRmLabels } )
384 btn->Enable( has_selected_row );
385
386 break;
387 }
389 {
390 m_btnUndo->Enable( has_selected_row );
391 break;
392 }
393 default:
394 break;
395 }
396
398 {
400 {
401 btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex()
402 && m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
403 }
404 }
405}
406
407
409{
411}
412
413
415{
417}
418
419
421{
423}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
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:97
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:241
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:176
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:117
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:47
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:116
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:187
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)
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition: sch_label.cpp:95
wxObjectDataPtr< SHEET_SYNCHRONIZATION_MODEL > SHEET_SYNCHRONIZATION_MODEL_PTR
LABEL_FLAG_SHAPE
Definition: sch_label.h:99
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:170