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 view->SetLayoutDirection( wxLayout_LeftToRight );
77 m_models.try_emplace( idx, std::move( model ) );
78
80 {
81 switch( col )
82 {
84 view->AppendIconTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
85 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
86 break;
88 view->AppendTextColumn( SHEET_SYNCHRONIZATION_MODEL::GetColName( col ), col,
89 wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
90 break;
91 }
92 }
93 }
94
95 for( auto& [idx, view] : m_views )
96 PostProcessModelSelection( idx, {} );
97}
98
99
101{
102 SHEET_SYNCHRONIZATION_ITEM_LIST labels_list, pins_list, associated_list;
103 auto labels_ori = m_sheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T );
104 std::vector<SCH_SHEET_PIN*> pins_ori = m_sheet->GetPins();
105
106 // De-duplicate the hierarchical labels list
107 std::set<wxString> dedup_labels_ori_text;
108 std::vector<SCH_HIERLABEL*> dedup_labels_ori;
109
110 for( const auto& item : labels_ori )
111 {
112 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
113
114 if( dedup_labels_ori_text.count( label->GetText() ) == 0 )
115 {
116 dedup_labels_ori_text.insert( label->GetText() );
117 dedup_labels_ori.push_back( label );
118 }
119 }
120
121 std::sort( dedup_labels_ori.begin(), dedup_labels_ori.end(),
122 []( const SCH_HIERLABEL* label1, const SCH_HIERLABEL* label2 )
123 {
124 return StrNumCmp( label1->GetText(), label2->GetText(), true ) < 0;
125 } );
126
127 auto check_matched = [&]( SCH_HIERLABEL* label )
128 {
129 for( size_t i = 0; i < pins_ori.size(); i++ )
130 {
131 SCH_SHEET_PIN* cur_pin = pins_ori[i];
132
133 if( label->GetText() == cur_pin->GetText() && label->GetShape() == cur_pin->GetShape() )
134 {
135 associated_list.push_back(
136 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label, cur_pin ) );
137 pins_ori.erase( pins_ori.begin() + i );
138 return;
139 }
140 }
141
142 labels_list.push_back(
143 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( label, m_sheet ) );
144 };
145
146 for( const auto& item : dedup_labels_ori )
147 check_matched( static_cast<SCH_HIERLABEL*>( item ) );
148
149 for( const auto& pin : pins_ori )
150 pins_list.push_back( std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>(
151 static_cast<SCH_SHEET_PIN*>( pin ), m_sheet ) );
152
153 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->UpdateItems( std::move( labels_list ) );
154 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->UpdateItems( std::move( pins_list ) );
155 m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->UpdateItems( std::move( associated_list ) );
156
158}
159
160
162{
163 return m_models.at( aKind );
164}
165
166
168{
169 return m_sheetFileName;
170}
171
172
176
177
183
184
186{
187 WXUNUSED( aEvent )
188
189 wxDataViewItemArray selected_items;
190 std::set<EDA_ITEM*> selected_items_set;
191 m_viewSheetPins->GetSelections( selected_items );
192
193 for( const auto& it : selected_items )
194 {
196 m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->GetSynchronizationItem( it ) )
197 selected_items_set.insert( item->GetItem() );
198 }
199
200 if( selected_items_set.empty() )
201 return;
202
203 m_agent.PlaceHieraLable( m_sheet, m_path, std::move( selected_items_set ) );
204}
205
206
208{
209 WXUNUSED( aEvent )
210 wxDataViewItemArray selected_items;
211 std::set<EDA_ITEM*> selected_items_set;
212 m_viewSheetLabels->GetSelections( selected_items );
213
214 for( const auto& it : selected_items )
215 {
217 m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->GetSynchronizationItem(
218 it ) )
219 selected_items_set.insert( item->GetItem() );
220 }
221
222 if( selected_items_set.empty() )
223 return;
224
225 m_agent.PlaceSheetPin( m_sheet, m_path, std::move( selected_items_set ) );
226}
227
228
230{
231 wxDataViewItem labelIdx = m_viewSheetLabels->GetSelection();
232 wxDataViewItem pinIdx = m_viewSheetPins->GetSelection();
233
234 for( auto& idx : { labelIdx, pinIdx } )
235 {
236 if( !idx.IsOk() )
237 return;
238 }
239
244
245 for( const auto& item : { labelItem, pinItem } )
246 {
247 if( !item )
248 return;
249 }
250
251 auto label_ptr =
252 std::static_pointer_cast<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( labelItem )->GetLabel();
253 auto pin_ptr =
254 std::static_pointer_cast<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( pinItem )->GetPin();
255
256 switch( direction )
257 {
259 m_agent.ModifyItem(
260 *pinItem,
261 [&]()
262 {
263 pin_ptr->SetText( label_ptr->GetText() );
264 pin_ptr->SetShape( label_ptr->GetShape() );
265 },
266 m_path );
267 break;
269 m_agent.ModifyItem(
270 *labelItem,
271 [&]()
272 {
273 label_ptr->SetText( pin_ptr->GetText() );
274 label_ptr->SetShape( pin_ptr->GetShape() );
275 },
276 m_path );
277 break;
278 }
279
281 std::make_shared<ASSOCIATED_SCH_LABEL_PIN>( label_ptr, pin_ptr ) );
283
284 for( auto idx :
286 {
287 PostProcessModelSelection( idx, {} );
288 }
289
291}
292
293
300
301
303{
304 WXUNUSED( aEvent )
306}
307
308
310{
311 WXUNUSED( aEvent )
313}
314
315
316void PANEL_SYNC_SHEET_PINS::OnBtnRmPinsClicked( wxCommandEvent& aEvent )
317{
318 WXUNUSED( aEvent )
319 wxDataViewItemArray array;
320 m_viewSheetPins->GetSelections( array );
324}
325
326
328{
329 WXUNUSED( aEvent )
330 wxDataViewItemArray array;
331 m_viewSheetLabels->GetSelections( array );
335}
336
337
338void PANEL_SYNC_SHEET_PINS::OnBtnUndoClicked( wxCommandEvent& aEvent )
339{
340 WXUNUSED( aEvent )
341 wxDataViewItemArray indexes;
342 m_viewAssociated->GetSelections( indexes );
343 auto items = m_models[SHEET_SYNCHRONIZATION_MODEL::ASSOCIATED]->TakeItems( indexes );
344
345 if( !items.size() )
346 return;
347
348 for( auto& item : items )
349 {
350 auto associated = std::static_pointer_cast<ASSOCIATED_SCH_LABEL_PIN>( item );
352 std::make_shared<SCH_HIERLABEL_SYNCHRONIZATION_ITEM>( associated->GetLabel(),
353 m_sheet ) );
355 std::make_shared<SCH_SHEET_PIN_SYNCHRONIZATION_ITEM>( associated->GetPin(),
356 m_sheet ) );
357 }
358
361}
362
363
364void PANEL_SYNC_SHEET_PINS::PostProcessModelSelection( int aIdex, wxDataViewItem const& aItem )
365{
366 if( aItem.IsOk() )
367 m_models[aIdex]->OnRowSelected( m_models[aIdex]->GetRow( aItem ) );
368 else
369 m_models[aIdex]->OnRowSelected( {} );
370
371 const bool has_selected_row = m_views[aIdex]->GetSelectedItemsCount() > 0;
372
373 switch( aIdex )
374 {
376 {
377 for( auto btn : { m_btnAddLabels, m_btnRmPins } )
378 btn->Enable( has_selected_row );
379
380 break;
381 }
383 {
384 for( auto btn : { m_btnAddSheetPins, m_btnRmLabels } )
385 btn->Enable( has_selected_row );
386
387 break;
388 }
390 {
391 m_btnUndo->Enable( has_selected_row );
392 break;
393 }
394 default:
395 break;
396 }
397
399 {
401 {
402 btn->Enable( m_models[SHEET_SYNCHRONIZATION_MODEL::SHEET_PIN]->HasSelectedIndex()
403 && m_models[SHEET_SYNCHRONIZATION_MODEL::HIRE_LABEL]->HasSelectedIndex() );
404 }
405 }
406}
407
408
413
414
419
420
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:98
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:180
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.
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:99
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:173