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, see <https://www.gnu.org/licenses/>.
19 */
20
22#include "sch_sheet_pin.h"
27
28#include <bitmaps.h>
29#include <map>
30#include <memory>
31#include <sch_label.h>
32#include <sch_sheet.h>
33#include <sch_pin.h>
34#include <sch_screen.h>
35#include <wx/bookctrl.h>
36#include <eda_item.h>
37#include <wx/string.h>
38#include <string_utils.h>
39
40// sch_label.cpp
41extern wxString getElectricalTypeLabel( LABEL_FLAG_SHAPE aType );
42
43PANEL_SYNC_SHEET_PINS::PANEL_SYNC_SHEET_PINS( wxWindow* aParent, SCH_SHEET* aSheet, wxNotebook* aNoteBook,
44 int aIndex, SHEET_SYNCHRONIZATION_AGENT& aAgent,
45 const SCH_SHEET_PATH& aPath ) :
47 m_sheet( aSheet ),
48 m_noteBook( aNoteBook ),
49 m_index( aIndex ),
50 m_sheetFileName( aSheet->GetFileName() ),
51 m_agent( aAgent ),
52 m_path( aPath ),
53 m_views( {
57 } )
58{
59 m_btnUsePinAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierar_pin ) );
60 m_btnUseLabelAsTemplate->SetBitmap( KiBitmapBundle( BITMAPS::add_hierarchical_label ) );
61 m_btnUndo->SetBitmap( KiBitmapBundle( BITMAPS::left ) );
62
63 m_labelSheetName->SetLabel( aSheet->GetFileName() );
64 m_labelSymName->SetLabel( aSheet->GetShownName( FOR_GUI ) );
65
66 for( auto& [idx, view] : m_views )
67 {
68 auto model = wxObjectDataPtr<SHEET_SYNCHRONIZATION_MODEL>(
69 new SHEET_SYNCHRONIZATION_MODEL( m_agent, m_sheet, m_path ) );
70 view->AssociateModel( model.get() );
71 view->SetLayoutDirection( wxLayout_LeftToRight );
72 m_models.try_emplace( idx, std::move( model ) );
73
75 {
76 switch( col )
77 {
79 view->AppendIconTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
80 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
81 break;
83 view->AppendTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
84 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
85 break;
86 }
87 }
88 }
89
90 for( auto& [idx, view] : m_views )
91 PostProcessModelSelection( idx, {} );
92}
93
94
96{
97 SHEET_SYNCHRONIZATION_ITEM_LIST labels_list, pins_list, associated_list;
98 auto labels_ori = m_sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T );
99 std::vector<SCH_SHEET_PIN*> pins_ori = m_sheet->GetPins();
100
101 // De-duplicate the hierarchical labels list
102 std::set<wxString> dedup_labels_ori_text;
103 std::vector<SCH_HIERLABEL*> dedup_labels_ori;
104
105 for( const auto& item : labels_ori )
106 {
107 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
108
109 if( dedup_labels_ori_text.count( label->GetText() ) == 0 )
110 {
111 dedup_labels_ori_text.insert( label->GetText() );
112 dedup_labels_ori.push_back( label );
113 }
114 }
115
116 std::sort( dedup_labels_ori.begin(), dedup_labels_ori.end(),
117 []( const SCH_HIERLABEL* label1, const SCH_HIERLABEL* label2 )
118 {
119 return StrNumCmp( label1->GetText(), label2->GetText(), true ) < 0;
120 } );
121
122 auto check_matched = [&]( SCH_HIERLABEL* label )
123 {
124 for( size_t i = 0; i < pins_ori.size(); i++ )
125 {
126 SCH_SHEET_PIN* cur_pin = pins_ori[i];
127
128 if( label->GetText() == cur_pin->GetText() && label->GetShape() == cur_pin->GetShape() )
129 {
130 associated_list.push_back(
131 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label, cur_pin ) );
132 pins_ori.erase( pins_ori.begin() + i );
133 return;
134 }
135 }
136
137 labels_list.push_back(
138 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( label, m_sheet ) );
139 };
140
141 for( const auto& item : dedup_labels_ori )
142 check_matched( static_cast<SCH_HIERLABEL*>( item ) );
143
144 for( const auto& pin : pins_ori )
145 pins_list.push_back( std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>(
146 static_cast<SCH_SHEET_PIN*>( pin ), m_sheet ) );
147
148 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->UpdateItems( std::move( labels_list ) );
149 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->UpdateItems( std::move( pins_list ) );
150 m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->UpdateItems( std::move( associated_list ) );
151
153}
154
155
157{
158 return m_models.at( aKind );
159}
160
161
163{
164 return m_sheetFileName;
165}
166
167
171
172
178
179
181{
182 WXUNUSED( aEvent )
183
184 wxDataViewItemArray selected_items;
185 std::set<EDA_ITEM*> selected_items_set;
186 m_viewSheetPins->GetSelections( selected_items );
187
188 for( const auto& it : selected_items )
189 {
191 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem( it ) )
192 selected_items_set.insert( item->GetItem() );
193 }
194
195 if( selected_items_set.empty() )
196 return;
197
198 m_agent.PlaceHieraLable( m_sheet, m_path, std::move( selected_items_set ) );
199}
200
201
203{
204 WXUNUSED( aEvent )
205 wxDataViewItemArray selected_items;
206 std::set<EDA_ITEM*> selected_items_set;
207 m_viewSheetLabels->GetSelections( selected_items );
208
209 for( const auto& it : selected_items )
210 {
212 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSynchronizationItem(
213 it ) )
214 selected_items_set.insert( item->GetItem() );
215 }
216
217 if( selected_items_set.empty() )
218 return;
219
220 m_agent.PlaceSheetPin( m_sheet, m_path, std::move( selected_items_set ) );
221}
222
223
225{
226 wxDataViewItem labelIdx = m_viewSheetLabels->GetSelection();
227 wxDataViewItem pinIdx = m_viewSheetPins->GetSelection();
228
229 for( auto& idx : { labelIdx, pinIdx } )
230 {
231 if( !idx.IsOk() )
232 return;
233 }
234
239
240 for( const auto& item : { labelItem, pinItem } )
241 {
242 if( !item )
243 return;
244 }
245
246 auto label_ptr =
247 std::static_pointer_cast<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( labelItem )->GetLabel();
248 auto pin_ptr =
249 std::static_pointer_cast<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( pinItem )->GetPin();
250
251 switch( direction )
252 {
254 m_agent.ModifyItem(
255 *pinItem,
256 [&]()
257 {
258 pin_ptr->SetText( label_ptr->GetText() );
259 pin_ptr->SetShape( label_ptr->GetShape() );
260 },
261 m_path );
262 break;
264 m_agent.ModifyItem(
265 *labelItem,
266 [&]()
267 {
268 label_ptr->SetText( pin_ptr->GetText() );
269 label_ptr->SetShape( pin_ptr->GetShape() );
270 },
271 m_path );
272 break;
273 }
274
276 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label_ptr, pin_ptr ) );
278
279 for( auto idx :
281 {
282 PostProcessModelSelection( idx, {} );
283 }
284
286}
287
288
295
296
298{
299 WXUNUSED( aEvent )
301}
302
303
305{
306 WXUNUSED( aEvent )
308}
309
310
311void PANEL_SYNC_SHEET_PINS::OnBtnRmPinsClicked( wxCommandEvent& aEvent )
312{
313 WXUNUSED( aEvent )
314 wxDataViewItemArray array;
315 m_viewSheetPins->GetSelections( array );
319}
320
321
323{
324 WXUNUSED( aEvent )
325 wxDataViewItemArray array;
326 m_viewSheetLabels->GetSelections( array );
330}
331
332
333void PANEL_SYNC_SHEET_PINS::OnBtnUndoClicked( wxCommandEvent& aEvent )
334{
335 WXUNUSED( aEvent )
336 wxDataViewItemArray indexes;
337 m_viewAssociated->GetSelections( indexes );
338 auto items = m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->TakeItems( indexes );
339
340 if( !items.size() )
341 return;
342
343 for( auto& item : items )
344 {
345 auto associated = std::static_pointer_cast<ASSOCIATED_SCH_LABEL_PIN>( item );
347 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( associated->GetLabel(),
348 m_sheet ) );
350 std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( associated->GetPin(),
351 m_sheet ) );
352 }
353
356}
357
358
359void PANEL_SYNC_SHEET_PINS::PostProcessModelSelection( int aIdex, wxDataViewItem const& aItem )
360{
361 if( aItem.IsOk() )
362 m_models[aIdex]->OnRowSelected( m_models[aIdex]->GetRow( aItem ) );
363 else
364 m_models[aIdex]->OnRowSelected( {} );
365
366 const bool has_selected_row = m_views[aIdex]->GetSelectedItemsCount() > 0;
367
368 switch( aIdex )
369 {
371 {
372 for( auto btn : { m_btnAddLabels, m_btnRmPins } )
373 btn->Enable( has_selected_row );
374
375 break;
376 }
378 {
379 for( auto btn : { m_btnAddSheetPins, m_btnRmLabels } )
380 btn->Enable( has_selected_row );
381
382 break;
383 }
385 {
386 m_btnUndo->Enable( has_selected_row );
387 break;
388 }
389 default:
390 break;
391 }
392
394 {
396 {
397 btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex()
398 && m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
399 }
400 }
401}
402
403
408
409
414
415
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
@ add_hierarchical_label
@ add_hierar_pin
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
PANEL_SYNC_SHEET_PINS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(666, 414), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
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:178
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
Agent for all the modifications while syncing the sheet pin and hierarchical label.
@ FOR_GUI
Definition common.h:89
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition sch_label.cpp:96
wxObjectDataPtr< SHEET_SYNCHRONIZATION_MODEL > SHEET_SYNCHRONIZATION_MODEL_PTR
LABEL_FLAG_SHAPE
Definition sch_label.h:97
std::vector< SHEET_SYNCHRONIZATION_ITE_PTR > SHEET_SYNCHRONIZATION_ITEM_LIST
std::shared_ptr< SHEET_SYNCHRONIZATION_ITEM > SHEET_SYNCHRONIZATION_ITE_PTR
KIBIS_MODEL * model
KIBIS_PIN * pin
@ SCH_HIER_LABEL_T
Definition typeinfo.h:165