KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_setup_netclasses.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) 2004-2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2009 Dick Hollenbeck, [email protected]
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <algorithm>
27#include <limits>
28
29#include <pgm_base.h>
30#include <eda_draw_frame.h>
31#include <bitmaps.h>
32#include <netclass.h>
33#include <gal/painter.h>
34#include <grid_tricks.h>
36#include <tool/tool_manager.h>
37#include <pcb_painter.h>
38#include <string_utils.h>
39#include <view/view.h>
43#include <widgets/wx_panel.h>
46#include <confirm.h>
47
48
49// columns of netclasses grid
50enum
51{
53
64
70
72};
73
74std::vector<BITMAPS> g_lineStyleIcons;
75wxArrayString g_lineStyleNames;
76
77
79 std::shared_ptr<NET_SETTINGS> aNetSettings,
80 const std::set<wxString>& aNetNames,
81 bool aIsEEschema ) :
82 PANEL_SETUP_NETCLASSES_BASE( aParentWindow ),
83 m_frame( aFrame ),
84 m_isEEschema( aIsEEschema ),
85 m_netSettings( std::move( aNetSettings ) ),
86 m_netNames( aNetNames ),
87 m_lastCheckedTicker( 0 ),
88 m_hoveredCol( -1 ),
89 m_lastNetclassGridWidth( -1 )
90{
91 // Clear and re-load each time. Language (or darkmode) might have changed.
92 g_lineStyleIcons.clear();
93 g_lineStyleNames.clear();
94
95 g_lineStyleIcons.push_back( BITMAPS::stroke_none );
96 g_lineStyleNames.push_back( _( "<Not defined>" ) );
97 g_lineStyleIcons.push_back( BITMAPS::stroke_solid );
98 g_lineStyleNames.push_back( _( "Solid" ) );
99 g_lineStyleIcons.push_back( BITMAPS::stroke_dash );
100 g_lineStyleNames.push_back( _( "Dashed" ) );
101 g_lineStyleIcons.push_back( BITMAPS::stroke_dot );
102 g_lineStyleNames.push_back( _( "Dotted" ) );
103 g_lineStyleIcons.push_back( BITMAPS::stroke_dashdot );
104 g_lineStyleNames.push_back( _( "Dash-Dot" ) );
105 g_lineStyleIcons.push_back( BITMAPS::stroke_dashdotdot );
106 g_lineStyleNames.push_back( _( "Dash-Dot-Dot" ) );
107
108 m_netclassesDirty = true;
109
110 m_schUnitsProvider = std::make_unique<UNITS_PROVIDER>( schIUScale, m_frame->GetUserUnits() );
111 m_pcbUnitsProvider = std::make_unique<UNITS_PROVIDER>( pcbIUScale, m_frame->GetUserUnits() );
112
113 m_netclassesPane->SetBorders( true, false, false, false );
114 m_membershipPane->SetBorders( true, false, false, false );
115
116 // Prevent Size events from firing before we are ready
117 Freeze();
118 m_netclassGrid->BeginBatch();
119 m_netclassGrid->SetUseNativeColLabels();
120 m_assignmentGrid->BeginBatch();
121 m_assignmentGrid->SetUseNativeColLabels();
122
123 m_splitter->SetMinimumPaneSize( FromDIP( m_splitter->GetMinimumPaneSize() ) );
124
125 wxASSERT( m_netclassGrid->GetNumberCols() == GRID_END );
126
127 // Calculate a min best size to handle longest usual numeric values:
128 int const min_best_width = m_netclassGrid->GetTextExtent( "555,555555 mils" ).x;
129
130 for( int i = 0; i < m_netclassGrid->GetNumberCols(); ++i )
131 {
132 // We calculate the column min size only from texts sizes, not using the initial col width
133 // as this initial width is sometimes strange depending on the language (wxGrid bug?)
134 int const min_width = m_netclassGrid->GetVisibleWidth( i, true, true );
135
136 int const weighted_min_best_width = ( i == GRID_LINESTYLE ) ? min_best_width * 3 / 2
137 : min_best_width;
138
139 // We use a "best size" >= min_best_width
140 m_originalColWidths[ i ] = std::max( min_width, weighted_min_best_width );
141 m_netclassGrid->SetColSize( i, m_originalColWidths[ i ] );
142
143 if( i >= GRID_FIRST_EESCHEMA )
145 else
147 }
148
150
151 if( m_isEEschema )
153 else
155
157
158 wxGridCellAttr* attr = new wxGridCellAttr;
159 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( PAGED_DIALOG::GetDialog( this ) ) );
160 attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( PAGED_DIALOG::GetDialog( this ),
161 m_netclassGrid ) );
162 m_netclassGrid->SetColAttr( GRID_SCHEMATIC_COLOR, attr );
163
164 attr = new wxGridCellAttr;
165 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( PAGED_DIALOG::GetDialog( this ) ) );
166 attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( PAGED_DIALOG::GetDialog( this ),
167 m_netclassGrid ) );
168 m_netclassGrid->SetColAttr( GRID_PCB_COLOR, attr );
169
170 attr = new wxGridCellAttr;
173 m_netclassGrid->SetColAttr( GRID_LINESTYLE, attr );
174
175 if( m_isEEschema )
176 {
177 m_importColorsButton->Hide();
178 }
179 else
180 {
181 m_colorDefaultHelpText->SetLabel(
182 _( "Set color to transparent to use layer default color." ) );
183 m_colorDefaultHelpText->GetParent()->Layout();
184 }
185
186 m_colorDefaultHelpText->SetFont( KIUI::GetInfoFont( this ).Italic() );
187
198
199
200 // Be sure the column labels are readable
202
203 // Membership combobox editors require a bit more room, so increase the row size of
204 // all our grids for consistency
205 m_netclassGrid->SetDefaultRowSize( m_netclassGrid->GetDefaultRowSize() + 4 );
206 m_assignmentGrid->SetDefaultRowSize( m_assignmentGrid->GetDefaultRowSize() + 4 );
207
208 m_netclassGrid->PushEventHandler( new GRID_TRICKS( m_netclassGrid ) );
209 m_assignmentGrid->PushEventHandler( new GRID_TRICKS( m_assignmentGrid ) );
210
211 m_netclassGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
212 m_assignmentGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
213
214 m_splitter->SetSashPosition( cfg->m_NetclassPanel.sash_pos );
215
216 m_addButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
217 m_removeButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
218
219 m_addAssignmentButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
220 m_removeAssignmentButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
221
222 m_moveUpButton->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
223 m_moveDownButton->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
224
225 // wxFormBuilder doesn't include this event...
226 m_netclassGrid->Connect( wxEVT_GRID_CELL_CHANGING,
228 nullptr, this );
229
230 // Handle tooltips for grid
231 m_netclassGrid->GetGridColLabelWindow()->Bind( wxEVT_MOTION,
233 this );
234
235 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
236
237 m_netclassGrid->EndBatch();
238 m_assignmentGrid->EndBatch();
239 Thaw();
240
241 Bind( wxEVT_IDLE,
242 [this]( wxIdleEvent& aEvent )
243 {
244 // Careful of consuming CPU in an idle event handler. Check the ticker first to
245 // see if there's even a possibility of the netclasses having changed.
247 {
248 wxWindow* dialog = wxGetTopLevelParent( this );
249 wxWindow* topLevelFocus = wxGetTopLevelParent( wxWindow::FindFocus() );
250
251 if( topLevelFocus == dialog && m_lastLoaded != m_netSettings->GetNetclasses() )
252 checkReload();
253 }
254 } );
255
256 m_matchingNets->SetFont( KIUI::GetInfoFont( this ) );
257}
258
259
261{
263 cfg->m_NetclassPanel.sash_pos = m_splitter->GetSashPosition();
264
265 if( m_isEEschema )
267 else
269
270 // Delete the GRID_TRICKS.
271 m_netclassGrid->PopEventHandler( true );
272 m_assignmentGrid->PopEventHandler( true );
273
274 m_netclassGrid->Disconnect( wxEVT_GRID_CELL_CHANGING,
276 nullptr, this );
277
278 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
279}
280
281
283{
284 auto netclassToGridRow =
285 [&]( int aRow, const NETCLASS* nc )
286 {
287 m_netclassGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() );
288
290 nc->GetWireWidthOpt() );
292 nc->GetBusWidthOpt() );
293
294 wxString colorAsString = nc->GetSchematicColor().ToCSSString();
295 m_netclassGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR, colorAsString );
296
297 if( nc->HasLineStyle() )
298 {
299 int lineStyleIdx = std::max( 0, nc->GetLineStyle() );
300
301 if( lineStyleIdx >= (int) g_lineStyleNames.size() + 1 )
302 lineStyleIdx = 0;
303
304 m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE,
305 g_lineStyleNames[lineStyleIdx + 1] );
306 }
307 else
308 {
309 // <Not defined> line style in list.
310 m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE,
311 g_lineStyleNames[0] );
312 }
313
314 m_netclassGrid->SetOptionalUnitValue( aRow, GRID_CLEARANCE, nc->GetClearanceOpt() );
316 nc->GetTrackWidthOpt() );
317 m_netclassGrid->SetOptionalUnitValue( aRow, GRID_VIASIZE, nc->GetViaDiameterOpt() );
318 m_netclassGrid->SetOptionalUnitValue( aRow, GRID_VIADRILL, nc->GetViaDrillOpt() );
320 nc->GetuViaDiameterOpt() );
321 m_netclassGrid->SetOptionalUnitValue( aRow, GRID_uVIADRILL, nc->GetuViaDrillOpt() );
323 nc->GetDiffPairWidthOpt() );
325 nc->GetDiffPairGapOpt() );
326
327 colorAsString = nc->GetPcbColor().ToCSSString();
328 m_netclassGrid->SetCellValue( aRow, GRID_PCB_COLOR, colorAsString );
329
330 if( nc->IsDefault() )
331 {
332 m_netclassGrid->SetReadOnly( aRow, GRID_NAME );
333 m_netclassGrid->SetReadOnly( aRow, GRID_PCB_COLOR );
334 m_netclassGrid->SetReadOnly( aRow, GRID_SCHEMATIC_COLOR );
335 m_netclassGrid->SetReadOnly( aRow, GRID_LINESTYLE );
336 }
337
338 setNetclassRowNullableEditors( aRow, nc->IsDefault() );
339 };
340
341 // Get the netclasses sorted by priority
342 std::vector<const NETCLASS*> netclasses;
343 netclasses.reserve( m_netSettings->GetNetclasses().size() );
344
345 for( const auto& [name, netclass] : m_netSettings->GetNetclasses() )
346 netclasses.push_back( netclass.get() );
347
348 std::sort( netclasses.begin(), netclasses.end(),
349 []( const NETCLASS* nc1, const NETCLASS* nc2 )
350 {
351 return nc1->GetPriority() < nc2->GetPriority();
352 } );
353
354 // Enter user-defined netclasses
356 m_netclassGrid->AppendRows( static_cast<int>( netclasses.size() ) );
357
358 int row = 0;
359
360 for( const NETCLASS* nc : netclasses )
361 netclassToGridRow( row++, nc );
362
363 // Enter the Default netclass.
364 m_netclassGrid->AppendRows( 1 );
365 netclassToGridRow( row, m_netSettings->GetDefaultNetclass().get() );
366
368 m_assignmentGrid->AppendRows( m_netSettings->GetNetclassPatternAssignments().size() );
369
370 row = 0;
371
372 for( const auto& [matcher, netclassName] : m_netSettings->GetNetclassPatternAssignments() )
373 {
374 m_assignmentGrid->SetCellValue( row, 0, matcher->GetPattern() );
375 m_assignmentGrid->SetCellValue( row, 1, netclassName );
376 row++;
377 }
378}
379
380
382{
383 // Set nullable editors
384 auto setCellEditor = [this, aRowId, aIsDefault]( int aCol )
385 {
386 GRID_CELL_MARK_AS_NULLABLE* cellEditor;
387
388 if( aIsDefault )
389 cellEditor = new GRID_CELL_MARK_AS_NULLABLE( false );
390 else
391 cellEditor = new GRID_CELL_MARK_AS_NULLABLE( true );
392
393 wxGridCellAttr* attr = m_netclassGrid->GetOrCreateCellAttr( aRowId, aCol );
394 attr->SetEditor( cellEditor );
395 attr->DecRef();
396 };
397
398 setCellEditor( GRID_WIREWIDTH );
399 setCellEditor( GRID_BUSWIDTH );
400 setCellEditor( GRID_CLEARANCE );
401 setCellEditor( GRID_TRACKSIZE );
402 setCellEditor( GRID_VIASIZE );
403 setCellEditor( GRID_VIADRILL );
404 setCellEditor( GRID_VIADRILL );
405 setCellEditor( GRID_uVIASIZE );
406 setCellEditor( GRID_uVIADRILL );
407 setCellEditor( GRID_DIFF_PAIR_WIDTH );
408 setCellEditor( GRID_DIFF_PAIR_GAP );
409}
410
411
413{
414 // MUST update the ticker before calling IsOK (or we'll end up re-entering through the idle
415 // event until we crash the stack).
417
418 if( IsOK( m_parent, _( "The netclasses have been changed outside the Setup dialog.\n"
419 "Do you wish to reload them?" ) ) )
420 {
421 m_lastLoaded = m_netSettings->GetNetclasses();
423 }
424}
425
426
427void PANEL_SETUP_NETCLASSES::onUnitsChanged( wxCommandEvent& aEvent )
428{
429 std::shared_ptr<NET_SETTINGS> tempNetSettings = std::make_shared<NET_SETTINGS>( nullptr, "" );
430 std::shared_ptr<NET_SETTINGS> saveNetSettings = m_netSettings;
431
432 m_netSettings = tempNetSettings;
433
435
436 m_schUnitsProvider->SetUserUnits( m_frame->GetUserUnits() );
437 m_pcbUnitsProvider->SetUserUnits( m_frame->GetUserUnits() );
438
440
441 m_netSettings = saveNetSettings;
442
443 aEvent.Skip();
444}
445
446
448{
449 m_lastLoaded = m_netSettings->GetNetclasses();
451
453 AdjustAssignmentGridColumns( GetSize().x * 3 / 5 );
454
455 return true;
456}
457
458
460{
462
463 wxArrayString netclassNames;
464
465 for( int ii = 0; ii < m_netclassGrid->GetNumberRows(); ii++ )
466 {
467 wxString netclassName = m_netclassGrid->GetCellValue( ii, GRID_NAME );
468
469 if( !netclassName.IsEmpty() )
470 netclassNames.push_back( netclassName );
471 }
472
473 wxGridCellAttr* attr = new wxGridCellAttr;
474 attr->SetEditor( new wxGridCellChoiceEditor( netclassNames ) );
475 m_assignmentGrid->SetColAttr( 1, attr );
476}
477
478
480{
481 if( !Validate() )
482 return false;
483
484 auto gridRowToNetclass =
485 [&]( int aRow, const std::shared_ptr<NETCLASS>& nc )
486 {
487 if( nc->IsDefault() )
488 nc->SetPriority( std::numeric_limits<int>::max() );
489 else
490 nc->SetPriority( aRow );
491
492 nc->SetName( m_netclassGrid->GetCellValue( aRow, GRID_NAME ) );
493
494 nc->SetWireWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_WIREWIDTH ) );
495 nc->SetBusWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_BUSWIDTH ) );
496
497 wxString lineStyle = m_netclassGrid->GetCellValue( aRow, GRID_LINESTYLE );
498 int lineIdx = g_lineStyleNames.Index( lineStyle );
499
500 if( lineIdx == 0 )
501 nc->SetLineStyle( std::optional<int>() );
502 else
503 nc->SetLineStyle( lineIdx - 1 );
504
505 wxASSERT_MSG( lineIdx >= 0, "Line style name not found." );
506
507 nc->SetClearance( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_CLEARANCE ) );
508 nc->SetTrackWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_TRACKSIZE ) );
509 nc->SetViaDiameter( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_VIASIZE ) );
510 nc->SetViaDrill( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_VIADRILL ) );
511 nc->SetuViaDiameter( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_uVIASIZE ) );
512 nc->SetuViaDrill( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_uVIADRILL ) );
513 nc->SetDiffPairWidth(
515 nc->SetDiffPairGap( m_netclassGrid->GetOptionalUnitValue( aRow,
517
518 if( !nc->IsDefault() )
519 {
520 wxString color = m_netclassGrid->GetCellValue( aRow, GRID_PCB_COLOR );
521 KIGFX::COLOR4D newPcbColor( color );
522
523 if( newPcbColor != KIGFX::COLOR4D::UNSPECIFIED )
524 nc->SetPcbColor( newPcbColor );
525
526 color = m_netclassGrid->GetCellValue( aRow, GRID_SCHEMATIC_COLOR );
527 KIGFX::COLOR4D newSchematicColor( color );
528
529 if( newSchematicColor != KIGFX::COLOR4D::UNSPECIFIED )
530 nc->SetSchematicColor( newSchematicColor );
531 }
532 };
533
534 m_netSettings->ClearNetclasses();
535
536 // Copy the default NetClass:
537 gridRowToNetclass( m_netclassGrid->GetNumberRows() - 1, m_netSettings->GetDefaultNetclass() );
538
539 // Copy other NetClasses:
540 for( int row = 0; row < m_netclassGrid->GetNumberRows() - 1; ++row )
541 {
542 auto nc =
543 std::make_shared<NETCLASS>( m_netclassGrid->GetCellValue( row, GRID_NAME ), false );
544 gridRowToNetclass( row, nc );
545 m_netSettings->SetNetclass( nc->GetName(), nc );
546 }
547
548 m_netSettings->ClearNetclassPatternAssignments();
549 m_netSettings->ClearAllCaches();
550
551 for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row )
552 {
553 wxString pattern = m_assignmentGrid->GetCellValue( row, 0 );
554 wxString netclass = m_assignmentGrid->GetCellValue( row, 1 );
555
556 m_netSettings->SetNetclassPatternAssignment( pattern, netclass );
557 }
558
559 return true;
560}
561
562
563bool PANEL_SETUP_NETCLASSES::validateNetclassName( int aRow, const wxString& aName,
564 bool focusFirst )
565{
566 wxString tmp = aName;
567
568 tmp.Trim( true );
569 tmp.Trim( false );
570
571 if( tmp.IsEmpty() )
572 {
573 wxString msg = _( "Netclass must have a name." );
574 PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_netclassGrid, aRow, GRID_NAME );
575 return false;
576 }
577
578 for( int ii = 0; ii < m_netclassGrid->GetNumberRows(); ii++ )
579 {
580 if( ii != aRow && m_netclassGrid->GetCellValue( ii, GRID_NAME ).CmpNoCase( tmp ) == 0 )
581 {
582 wxString msg = _( "Netclass name already in use." );
584 focusFirst ? aRow : ii, GRID_NAME );
585 return false;
586 }
587 }
588
589 return true;
590}
591
592
594{
595 if( event.GetCol() == GRID_NAME )
596 {
597 if( validateNetclassName( event.GetRow(), event.GetString() ) )
598 {
599 wxString oldName = m_netclassGrid->GetCellValue( event.GetRow(), GRID_NAME );
600 wxString newName = event.GetString();
601
602 if( !oldName.IsEmpty() )
603 {
604 for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row )
605 {
606 if( m_assignmentGrid->GetCellValue( row, 1 ) == oldName )
607 m_assignmentGrid->SetCellValue( row, 1, newName );
608 }
609 }
610
611 m_netclassesDirty = true;
612 }
613 else
614 {
615 event.Veto();
616 }
617 }
618}
619
620
622{
623 int col = m_netclassGrid->XToCol( aEvent.GetPosition().x );
624
625 if( aEvent.Moving() || aEvent.Entering() )
626 {
627 aEvent.Skip();
628
629 if( col == wxNOT_FOUND )
630 {
631 m_netclassGrid->GetGridColLabelWindow()->UnsetToolTip();
632 return;
633 }
634
635 if( col == m_hoveredCol )
636 return;
637
638 m_hoveredCol = col;
639
640 wxString tip;
641
642 switch( col )
643 {
644 case GRID_CLEARANCE: tip = _( "Minimum copper clearance" ); break;
645 case GRID_TRACKSIZE: tip = _( "Minimum track width" ); break;
646 case GRID_VIASIZE: tip = _( "Via pad diameter" ); break;
647 case GRID_VIADRILL: tip = _( "Via plated hole diameter" ); break;
648 case GRID_uVIASIZE: tip = _( "Microvia pad diameter" ); break;
649 case GRID_uVIADRILL: tip = _( "Microvia plated hole diameter" ); break;
650 case GRID_DIFF_PAIR_WIDTH: tip = _( "Differential pair track width" ); break;
651 case GRID_DIFF_PAIR_GAP: tip = _( "Differential pair gap" ); break;
652 case GRID_WIREWIDTH: tip = _( "Schematic wire thickness" ); break;
653 case GRID_BUSWIDTH: tip = _( "Bus wire thickness" ); break;
654 case GRID_SCHEMATIC_COLOR: tip = _( "Schematic wire color" ); break;
655 case GRID_LINESTYLE: tip = _( "Schematic wire line style" ); break;
656 case GRID_PCB_COLOR: tip = _( "PCB netclass color" ); break;
657 }
658
659 m_netclassGrid->GetGridColLabelWindow()->UnsetToolTip();
660 m_netclassGrid->GetGridColLabelWindow()->SetToolTip( tip );
661 }
662 else if( aEvent.Leaving() )
663 {
664 m_netclassGrid->GetGridColLabelWindow()->UnsetToolTip();
665 aEvent.Skip();
666 }
667
668 aEvent.Skip();
669}
670
671
673{
675 return;
676
677 m_netclassGrid->InsertRows();
678
679 // Set defaults where required
680 wxString colorAsString = KIGFX::COLOR4D::UNSPECIFIED.ToCSSString();
681 m_netclassGrid->SetCellValue( 0, GRID_PCB_COLOR, colorAsString );
682 m_netclassGrid->SetCellValue( 0, GRID_SCHEMATIC_COLOR, colorAsString );
683 m_netclassGrid->SetCellValue( 0, GRID_LINESTYLE, g_lineStyleNames[0] );
684
685 // Set the row nullable editors
687
688 m_netclassGrid->MakeCellVisible( 0, 0 );
689 m_netclassGrid->SetGridCursor( 0, 0 );
690
691 m_netclassGrid->EnableCellEditControl( true );
692 m_netclassGrid->ShowCellEditControl();
693
694 m_netclassesDirty = true;
695}
696
697
699{
701 return;
702
703 int curRow = m_netclassGrid->GetGridCursorRow();
704
705 if( curRow < 0 )
706 {
707 return;
708 }
709 else if( curRow == m_netclassGrid->GetNumberRows() - 1 )
710 {
711 wxWindow* topLevelParent = wxGetTopLevelParent( this );
712
713 DisplayErrorMessage( topLevelParent, _( "The default net class is required." ) );
714 return;
715 }
716
717 // reset the net class to default for members of the removed class
718 wxString classname = m_netclassGrid->GetCellValue( curRow, GRID_NAME );
719
720 for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row )
721 {
722 if( m_assignmentGrid->GetCellValue( row, 1 ) == classname )
723 m_assignmentGrid->SetCellValue( row, 1, NETCLASS::Default );
724 }
725
726 m_netclassGrid->DeleteRows( curRow, 1 );
727
728 m_netclassGrid->MakeCellVisible( std::max( 0, curRow-1 ), m_netclassGrid->GetGridCursorCol() );
729 m_netclassGrid->SetGridCursor( std::max( 0, curRow-1 ), m_netclassGrid->GetGridCursorCol() );
730
731 m_netclassesDirty = true;
732}
733
734
736{
737 if( aWidth != m_lastNetclassGridWidth )
738 {
740
741 // Account for scroll bars
742 aWidth -= ( m_netclassGrid->GetSize().x - m_netclassGrid->GetClientSize().x );
743
744 for( int i = 1; i < m_netclassGrid->GetNumberCols(); i++ )
745 {
746 if( m_netclassGrid->GetColSize( i ) > 0 )
747 {
748 m_netclassGrid->SetColSize( i, m_originalColWidths[ i ] );
749 aWidth -= m_originalColWidths[ i ];
750 }
751 }
752
753 m_netclassGrid->SetColSize( 0, std::max( aWidth - 2, m_originalColWidths[ 0 ] ) );
754 }
755}
756
757
759{
760 AdjustNetclassGridColumns( event.GetSize().GetX() );
761
762 event.Skip();
763}
764
765
767{
769 return;
770
771 int row = m_assignmentGrid->GetNumberRows();
772 m_assignmentGrid->AppendRows();
773
774 m_assignmentGrid->SetCellValue( row, 1, m_netSettings->GetDefaultNetclass()->GetName() );
775
776 m_assignmentGrid->MakeCellVisible( row, 0 );
777 m_assignmentGrid->SetGridCursor( row, 0 );
778
779 m_assignmentGrid->EnableCellEditControl( true );
780 m_assignmentGrid->ShowCellEditControl();
781}
782
783
785{
787 return;
788
789 int curRow = m_assignmentGrid->GetGridCursorRow();
790
791 if( curRow < 0 )
792 return;
793
794 m_assignmentGrid->DeleteRows( curRow, 1 );
795
796 if( m_assignmentGrid->GetNumberRows() > 0 )
797 {
798 m_assignmentGrid->MakeCellVisible( std::max( 0, curRow-1 ), 0 );
799 m_assignmentGrid->SetGridCursor( std::max( 0, curRow-1 ), 0 );
800 }
801}
802
803
805{
806 const std::map<wxString, std::shared_ptr<NETCLASS>>& netclasses =
807 m_netSettings->GetNetclasses();
808
809 for( int row = 0; row < m_netclassGrid->GetNumberRows() - 1; ++row )
810 {
811 wxString netclassName = m_netclassGrid->GetCellValue( row, GRID_NAME );
812
813 if( netclasses.find( netclassName ) != netclasses.end() )
814 {
815 const KIGFX::COLOR4D ncColor = netclasses.at( netclassName )->GetSchematicColor();
816 m_netclassGrid->SetCellValue( row, GRID_PCB_COLOR, ncColor.ToCSSString() );
817 }
818 }
819}
820
821
823{
824 // Account for scroll bars
825 aWidth -= ( m_assignmentGrid->GetSize().x - m_assignmentGrid->GetClientSize().x );
826
827 int classNameWidth = 160;
828 m_assignmentGrid->SetColSize( 1, classNameWidth );
829 m_assignmentGrid->SetColSize( 0, std::max( aWidth - classNameWidth, classNameWidth ) );
830}
831
832
834{
835 AdjustAssignmentGridColumns( event.GetSize().GetX() );
836
837 event.Skip();
838}
839
840
841void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event )
842{
844 {
846 m_netclassesDirty = false;
847 }
848
850 {
851 AdjustNetclassGridColumns( GetSize().x - 1 );
853 }
854
855 if( m_assignmentGrid->GetNumberRows() == 0 )
856 return;
857
858 wxString pattern;
859 int row = m_assignmentGrid->GetGridCursorRow();
860 int col = m_assignmentGrid->GetGridCursorCol();
861
862 if( row >= 0 )
863 pattern = m_assignmentGrid->GetCellValue( row, 0 );
864
865 if( col == 0 && m_assignmentGrid->IsCellEditControlShown() )
866 {
867 wxGridCellEditor* cellEditor = m_assignmentGrid->GetCellEditor( row, 0 );
868
869 if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
870 pattern = txt->GetValue();
871
872 cellEditor->DecRef();
873 }
874
875 if( pattern != m_lastPattern )
876 {
878
879 if( !pattern.IsEmpty() )
880 {
881 EDA_COMBINED_MATCHER matcher( pattern, CTX_NETCLASS );
882
883 m_matchingNets->Report( wxString::Format( _( "<b>Nets matching '%s':</b>" ),
884 pattern ) );
885
886 for( const wxString& net : m_netNames )
887 {
888 if( matcher.StartsWith( net ) )
889 m_matchingNets->Report( net );
890 }
891 }
892
894 m_lastPattern = pattern;
895 }
896}
897
898
900{
902 return false;
903
904 wxString msg;
905
906 // Test net class parameters.
907 for( int row = 0; row < m_netclassGrid->GetNumberRows(); row++ )
908 {
909 wxString netclassName = m_netclassGrid->GetCellValue( row, GRID_NAME );
910 netclassName.Trim( true );
911 netclassName.Trim( false );
912
913 if( !validateNetclassName( row, netclassName, false ) )
914 return false;
915 }
916
917 return true;
918}
919
920
921void PANEL_SETUP_NETCLASSES::ImportSettingsFrom( const std::shared_ptr<NET_SETTINGS>& aNetSettings )
922{
923 std::shared_ptr<NET_SETTINGS> savedSettings = m_netSettings;
924
925 m_netSettings = aNetSettings;
927
929
930 m_netclassGrid->ForceRefresh();
931 m_assignmentGrid->ForceRefresh();
932
933 m_netSettings = std::move( savedSettings );
934}
935
936
938{
940 return;
941
942 // Work out which rows are selected
943 std::vector<int> selectedRows;
944
945 for( int i = 0; i < m_netclassGrid->GetNumberRows(); ++i )
946 {
947 if( m_netclassGrid->IsInSelection( i, 0 ) )
948 selectedRows.push_back( i );
949 }
950
951 // Only move one row at a time
952 if( selectedRows.size() != 1 )
953 return;
954
955 // Can't move the first netclass, nor move the Default netclass
956 if( selectedRows[0] == 0 || selectedRows[0] == ( m_netclassGrid->GetNumberRows() - 1 ) )
957 return;
958
959 int newRowId = selectedRows[0] - 1;
960 m_netclassGrid->InsertRows( newRowId );
961
962 for( int col = 0; col < m_netclassGrid->GetNumberCols(); col++ )
963 m_netclassGrid->SetCellValue( newRowId, col,
964 m_netclassGrid->GetCellValue( newRowId + 2, col ) );
965
966 // Set the row nullable editors
967 setNetclassRowNullableEditors( newRowId, false );
968
969 m_netclassGrid->DeleteRows( newRowId + 2, 1 );
970 m_netclassGrid->MakeCellVisible( newRowId, 0 );
971 m_netclassGrid->SetGridCursor( newRowId, 0 );
972
973 m_netclassesDirty = true;
974}
975
976
978{
980 return;
981
982 // Work out which rows are selected
983 std::vector<int> selectedRows;
984
985 for( int i = 0; i < m_netclassGrid->GetNumberRows(); ++i )
986 {
987 if( m_netclassGrid->IsInSelection( i, 0 ) )
988 selectedRows.push_back( i );
989 }
990
991 // Only move one row at a time
992 if( selectedRows.size() != 1 )
993 return;
994
995 // Can't move the last row down, nor move the Default netclass
996 if( selectedRows[0] == ( m_netclassGrid->GetNumberRows() - 2 )
997 || selectedRows[0] == ( m_netclassGrid->GetNumberRows() - 1 ) )
998 return;
999
1000 int newRowId = selectedRows[0] + 2;
1001 m_netclassGrid->InsertRows( newRowId );
1002
1003 for( int col = 0; col < m_netclassGrid->GetNumberCols(); col++ )
1004 {
1005 m_netclassGrid->SetCellValue( newRowId, col,
1006 m_netclassGrid->GetCellValue( newRowId - 2, col ) );
1007 }
1008
1009 m_netclassGrid->DeleteRows( newRowId - 2, 1 );
1010 m_netclassGrid->MakeCellVisible( newRowId - 1, 0 );
1011 m_netclassGrid->SetGridCursor( newRowId - 1, 0 );
1012
1013 m_netclassesDirty = true;
1014}
int color
Definition: DXF_plotter.cpp:60
const char * name
Definition: DXF_plotter.cpp:59
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
NETCLASS_PANEL m_NetclassPanel
bool StartsWith(const wxString &aTerm)
The base class for create windows for drawing purpose.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
wxString ToCSSString() const
Definition: color4d.cpp:147
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:398
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:45
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:47
static PAGED_DIALOG * GetDialog(wxWindow *aWindow)
void SetError(const wxString &aMessage, const wxString &aPageName, int aCtrlId, int aRow=-1, int aCol=-1)
Class PANEL_SETUP_NETCLASSES_BASE.
void OnImportColorsClick(wxCommandEvent &event) override
std::map< int, int > m_originalColWidths
void OnUpdateUI(wxUpdateUIEvent &event) override
void OnSizeAssignmentGrid(wxSizeEvent &event) override
PANEL_SETUP_NETCLASSES(wxWindow *aParentWindow, EDA_DRAW_FRAME *aFrame, std::shared_ptr< NET_SETTINGS > aSettings, const std::set< wxString > &aNetNames, bool isEEschema)
void OnRemoveNetclassClick(wxCommandEvent &event) override
void OnRemoveAssignmentClick(wxCommandEvent &event) override
std::map< wxString, std::shared_ptr< NETCLASS > > m_lastLoaded
void ImportSettingsFrom(const std::shared_ptr< NET_SETTINGS > &aNetSettings)
void onUnitsChanged(wxCommandEvent &aEvent)
void OnNetclassGridCellChanging(wxGridEvent &event)
void setNetclassRowNullableEditors(int aRowId, bool aIsDefault)
bool validateNetclassName(int aRow, const wxString &aName, bool focusFirst=true)
std::unique_ptr< UNITS_PROVIDER > m_pcbUnitsProvider
void OnNetclassGridMouseEvent(wxMouseEvent &event)
void OnAddAssignmentClick(wxCommandEvent &event) override
void AdjustAssignmentGridColumns(int aWidth)
void OnMoveNetclassUpClick(wxCommandEvent &event) override
std::set< wxString > m_netNames
void OnAddNetclassClick(wxCommandEvent &event) override
std::unique_ptr< UNITS_PROVIDER > m_schUnitsProvider
std::bitset< 64 > m_shownColumns
void OnSizeNetclassGrid(wxSizeEvent &event) override
void AdjustNetclassGridColumns(int aWidth)
std::shared_ptr< NET_SETTINGS > m_netSettings
void OnMoveNetclassDownClick(wxCommandEvent &event) override
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:689
int GetNetclassesTicker() const
Definition: project.h:117
int GetTextVarsTicker() const
Definition: project.h:114
void SetBitmap(const wxBitmapBundle &aBmp)
EDA_UNITS GetUserUnits() const
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculate the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:778
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:496
void SetOptionalUnitValue(int aRow, int aCol, std::optional< int > aValue)
Set a unitized cell's optional value.
Definition: wx_grid.cpp:760
void EnsureColLabelsVisible()
Ensure the height of the row displaying the column labels is enough, even if labels are multiline tex...
Definition: wx_grid.cpp:819
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:466
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:485
std::optional< int > GetOptionalUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
Definition: wx_grid.cpp:728
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition: wx_grid.h:128
void SetUnitsProvider(UNITS_PROVIDER *aProvider, int aCol=0)
Set a EUNITS_PROVIDER to enable use of unit- and eval-based Getters.
Definition: wx_grid.cpp:698
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:193
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:646
void Clear()
Delete the stored messages.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
void Flush()
Build the HTML messages page.
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
Definition: wx_panel.h:39
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:250
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
#define _(s)
@ CTX_NETCLASS
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:155
STL namespace.
std::vector< BITMAPS > g_lineStyleIcons
@ GRID_FIRST_PCBNEW
@ GRID_DIFF_PAIR_GAP
@ GRID_SCHEMATIC_COLOR
@ GRID_DIFF_PAIR_WIDTH
@ GRID_FIRST_EESCHEMA
wxArrayString g_lineStyleNames
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:1073
see class PGM_BASE