KiCad PCB EDA Suite
dialog_lib_edit_pin_table.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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
25 #include "lib_pin.h"
26 #include "pin_number.h"
27 #include "grid_tricks.h"
29 #include <widgets/wx_grid.h>
30 #include <queue>
31 #include <base_units.h>
32 #include <bitmaps.h>
33 #include <wx/bmpcbox.h>
34 #include <kiface_i.h>
35 #include <kicad_string.h>
36 #include <confirm.h>
37 
38 #define PinTableShownColumnsKey wxT( "PinTableShownColumns" )
39 
40 
41 static std::vector<BITMAP_DEF> g_typeIcons;
42 static wxArrayString g_typeNames;
43 
44 static std::vector<BITMAP_DEF> g_shapeIcons;
45 static wxArrayString g_shapeNames;
46 
47 static std::vector<BITMAP_DEF> g_orientationIcons;
48 static wxArrayString g_orientationNames;
49 
50 
51 class PIN_TABLE_DATA_MODEL : public wxGridTableBase
52 {
53 
54 private:
55  // Because the rows of the grid can either be a single pin or a group of pins, the
56  // data model is a 2D vector. If we're in the single pin case, each row's LIB_PINS
57  // contains only a single pin.
58  std::vector<LIB_PINS> m_rows;
59 
61  bool m_edited;
62 
63 public:
65  m_userUnits( aUserUnits ), m_edited( false )
66  {}
67 
68  int GetNumberRows() override { return (int) m_rows.size(); }
69  int GetNumberCols() override { return COL_COUNT; }
70 
71  wxString GetColLabelValue( int aCol ) override
72  {
73  switch( aCol )
74  {
75  case COL_NUMBER: return _( "Number" );
76  case COL_NAME: return _( "Name" );
77  case COL_TYPE: return _( "Electrical Type" );
78  case COL_SHAPE: return _( "Graphic Style" );
79  case COL_ORIENTATION: return _( "Orientation" );
80  case COL_NUMBER_SIZE: return _( "Number Text Size" );
81  case COL_NAME_SIZE: return _( "Name Text Size" );
82  case COL_LENGTH: return _( "Length" );
83  case COL_POSX: return _( "X Position" );
84  case COL_POSY: return _( "Y Position" );
85  default: wxFAIL; return wxEmptyString;
86  }
87  }
88 
89  bool IsEmptyCell( int row, int col ) override
90  {
91  return false; // don't allow adjacent cell overflow, even if we are actually empty
92  }
93 
94  wxString GetValue( int aRow, int aCol ) override
95  {
96  return GetValue( m_rows[ aRow ], aCol, m_userUnits );
97  }
98 
99  static wxString GetValue( const LIB_PINS& pins, int aCol, EDA_UNITS_T aUserUnits )
100  {
101  wxString fieldValue;
102 
103  if( pins.empty())
104  return fieldValue;
105 
106  for( LIB_PIN* pin : pins )
107  {
108  wxString val;
109 
110  switch( aCol )
111  {
112  case COL_NUMBER:
113  val = pin->GetNumber();
114  break;
115  case COL_NAME:
116  val = pin->GetName();
117  break;
118  case COL_TYPE:
119  val = g_typeNames[ pin->GetType() ];
120  break;
121  case COL_SHAPE:
122  val = g_shapeNames[ pin->GetShape() ];
123  break;
124  case COL_ORIENTATION:
125  val = g_orientationNames[ LIB_PIN::GetOrientationIndex( pin->GetOrientation() ) ];
126  break;
127  case COL_NUMBER_SIZE:
128  val = StringFromValue( aUserUnits, pin->GetNumberTextSize(), true, true );
129  break;
130  case COL_NAME_SIZE:
131  val = StringFromValue( aUserUnits, pin->GetNameTextSize(), true, true );
132  break;
133  case COL_LENGTH:
134  val = StringFromValue( aUserUnits, pin->GetLength(), true );
135  break;
136  case COL_POSX:
137  val = StringFromValue( aUserUnits, pin->GetPosition().x, true );
138  break;
139  case COL_POSY:
140  val = StringFromValue( aUserUnits, pin->GetPosition().y, true );
141  break;
142  default:
143  wxFAIL;
144  break;
145  }
146 
147  if( aCol == COL_NUMBER )
148  {
149  if( fieldValue.length() )
150  fieldValue += wxT( ", " );
151  fieldValue += val;
152  }
153  else
154  {
155  if( !fieldValue.Length() )
156  fieldValue = val;
157  else if( val != fieldValue )
158  fieldValue = INDETERMINATE;
159  }
160  }
161 
162  return fieldValue;
163  }
164 
165  void SetValue( int aRow, int aCol, const wxString &aValue ) override
166  {
167  if( aValue == INDETERMINATE )
168  return;
169 
170  LIB_PINS pins = m_rows[ aRow ];
171 
172  for( LIB_PIN* pin : pins )
173  {
174  switch( aCol )
175  {
176  case COL_NUMBER:
177  pin->SetNumber( aValue );
178  break;
179  case COL_NAME:
180  pin->SetName( aValue );
181  break;
182  case COL_TYPE:
183  if( g_typeNames.Index( aValue ) != wxNOT_FOUND )
184  pin->SetType( (ELECTRICAL_PINTYPE) g_typeNames.Index( aValue ), false );
185 
186  break;
187  case COL_SHAPE:
188  if( g_shapeNames.Index( aValue ) != wxNOT_FOUND )
189  pin->SetShape( (GRAPHIC_PINSHAPE) g_shapeNames.Index( aValue ) );
190 
191  break;
192  case COL_ORIENTATION:
193  if( g_orientationNames.Index( aValue ) != wxNOT_FOUND )
194  pin->SetOrientation( LIB_PIN::GetOrientationCode(
195  g_orientationNames.Index( aValue ) ), false );
196  break;
197  case COL_NUMBER_SIZE:
198  pin->SetNumberTextSize( ValueFromString( m_userUnits, aValue, true ) );
199  break;
200  case COL_NAME_SIZE:
201  pin->SetNameTextSize( ValueFromString( m_userUnits, aValue, true ) );
202  break;
203  case COL_LENGTH:
204  pin->SetLength( ValueFromString( m_userUnits, aValue ) );
205  break;
206  case COL_POSX:
207  pin->SetPinPosition( wxPoint( ValueFromString( m_userUnits, aValue ),
208  pin->GetPosition().y ) );
209  break;
210  case COL_POSY:
211  pin->SetPinPosition( wxPoint( pin->GetPosition().x,
212  ValueFromString( m_userUnits, aValue ) ) );
213  break;
214  default:
215  wxFAIL;
216  break;
217  }
218  }
219 
220  m_edited = true;
221  }
222 
223  static int findRow( const std::vector<LIB_PINS>& aRowSet, const wxString& aName )
224  {
225  for( size_t i = 0; i < aRowSet.size(); ++i )
226  {
227  if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
228  return i;
229  }
230 
231  return -1;
232  }
233 
234  static bool compare( const LIB_PINS& lhs, const LIB_PINS& rhs,
235  int sortCol, bool ascending, EDA_UNITS_T units )
236  {
237  wxString lhStr = GetValue( lhs, sortCol, units );
238  wxString rhStr = GetValue( rhs, sortCol, units );
239 
240  if( lhStr == rhStr )
241  {
242  // Secondary sort key is always COL_NUMBER
243  sortCol = COL_NUMBER;
244  lhStr = GetValue( lhs, sortCol, units );
245  rhStr = GetValue( rhs, sortCol, units );
246  }
247 
248  bool cmp;
249 
250  switch( sortCol )
251  {
252  case COL_NUMBER:
253  case COL_NAME:
254  cmp = PinNumbers::Compare( lhStr, rhStr ) < 0;
255  break;
256  case COL_NUMBER_SIZE:
257  case COL_NAME_SIZE:
258  cmp = ValueFromString( units, lhStr, true ) < ValueFromString( units, rhStr, true );
259  break;
260  case COL_LENGTH:
261  case COL_POSX:
262  case COL_POSY:
263  cmp = ValueFromString( units, lhStr ) < ValueFromString( units, rhStr );
264  break;
265  default:
266  cmp = StrNumCmp( lhStr, rhStr ) < 0;
267  break;
268  }
269 
270  return ascending == cmp;
271  }
272 
273  void RebuildRows( LIB_PINS& aPins, bool groupByName )
274  {
275  if ( GetView() )
276  {
277  // Commit any pending in-place edits before the row gets moved out from under
278  // the editor.
279  dynamic_cast<WX_GRID*>( GetView() )->CommitPendingChanges( true );
280 
281  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, m_rows.size() );
282  GetView()->ProcessTableMessage( msg );
283  }
284 
285  m_rows.clear();
286 
287  for( LIB_PIN* pin : aPins )
288  {
289  int rowIndex = -1;
290 
291  if( groupByName )
292  rowIndex = findRow( m_rows, pin->GetName() );
293 
294  if( rowIndex < 0 )
295  {
296  m_rows.emplace_back( LIB_PINS() );
297  rowIndex = m_rows.size() - 1;
298  }
299 
300  m_rows[ rowIndex ].push_back( pin );
301  }
302 
303  int sortCol = 0;
304  bool ascending = true;
305 
306  if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
307  {
308  sortCol = GetView()->GetSortingColumn();
309  ascending = GetView()->IsSortOrderAscending();
310  }
311 
312  SortRows( sortCol, ascending );
313 
314  if ( GetView() )
315  {
316  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_rows.size() );
317  GetView()->ProcessTableMessage( msg );
318  }
319  }
320 
321  void SortRows( int aSortCol, bool ascending )
322  {
323  std::sort( m_rows.begin(), m_rows.end(),
324  [ aSortCol, ascending, this ]( LIB_PINS lhs, LIB_PINS rhs ) -> bool
325  { return compare( lhs, rhs, aSortCol, ascending, m_userUnits ); } );
326  }
327 
328  void AppendRow( LIB_PIN* aPin )
329  {
330  LIB_PINS row;
331  row.push_back( aPin );
332  m_rows.push_back( row );
333 
334  if ( GetView() )
335  {
336  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
337  GetView()->ProcessTableMessage( msg );
338  }
339  }
340 
341  LIB_PINS RemoveRow( int aRow )
342  {
343  LIB_PINS removedRow = m_rows[ aRow ];
344 
345  m_rows.erase( m_rows.begin() + aRow );
346 
347  if ( GetView() )
348  {
349  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
350  GetView()->ProcessTableMessage( msg );
351  }
352 
353  return removedRow;
354  }
355 
356  bool IsEdited()
357  {
358  return m_edited;
359  }
360 };
361 
362 
365  m_part( aPart )
366 {
368 
369  if( g_typeNames.empty())
370  {
371  for( unsigned i = 0; i < PINTYPE_COUNT; ++i )
372  g_typeIcons.push_back( GetBitmap( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
373  for( unsigned i = 0; i < PINTYPE_COUNT; ++i )
374  g_typeNames.push_back( GetText( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
375  g_typeNames.push_back( INDETERMINATE );
376 
377  for( unsigned i = 0; i < PINSHAPE_COUNT; ++i )
378  g_shapeIcons.push_back( GetBitmap( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
379  for( unsigned i = 0; i < PINSHAPE_COUNT; ++i )
380  g_shapeNames.push_back( GetText( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
381  g_shapeNames.push_back( INDETERMINATE );
382 
383  for( unsigned i = 0; i < LIB_PIN::GetOrientationNames().size(); ++i )
386  g_orientationNames.push_back( INDETERMINATE );
387  }
388 
390 
391  // Save original columns widths so we can do proportional sizing.
392  for( int i = 0; i < COL_COUNT; ++i )
393  m_originalColWidths[ i ] = m_grid->GetColSize( i );
394 
395  // Give a bit more room for combobox editors
396  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
397 
399  m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
400 
401  // Show/hide columns according to the user's preference
402  m_config->Read( PinTableShownColumnsKey, &m_columnsShown, wxT( "0 1 2 3 4 8 9" ) );
404 
405  // Set special attributes
406  wxGridCellAttr* attr;
407 
408  attr = new wxGridCellAttr;
409  attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_typeIcons, g_typeNames ) );
410  attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_typeIcons, g_typeNames ) );
411  m_grid->SetColAttr( COL_TYPE, attr );
412 
413  attr = new wxGridCellAttr;
414  attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_shapeIcons, g_shapeNames ) );
415  attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_shapeIcons, g_shapeNames ) );
416  m_grid->SetColAttr( COL_SHAPE, attr );
417 
418  attr = new wxGridCellAttr;
421  m_grid->SetColAttr( COL_ORIENTATION, attr );
422 
423  /* Right-aligned position values look much better, but only MSW and GTK2+
424  * currently support righ-aligned textEditCtrls, so the text jumps on all
425  * the other platforms when you edit it.
426  attr = new wxGridCellAttr;
427  attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_TOP );
428  m_grid->SetColAttr( COL_POSX, attr );
429 
430  attr = new wxGridCellAttr;
431  attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_TOP );
432  m_grid->SetColAttr( COL_POSY, attr );
433  */
434 
435  m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
436  m_deleteButton->SetBitmap( KiBitmap( trash_xpm ) );
437  m_refreshButton->SetBitmap( KiBitmap( refresh_xpm ) );
438 
439  GetSizer()->SetSizeHints(this);
440  Centre();
441 
442  m_ButtonsOK->SetDefault();
443  m_initialized = true;
444  m_modified = false;
445  m_width = 0;
446 
447  // Connect Events
448  m_grid->Connect( wxEVT_GRID_COL_SORT, wxGridEventHandler( DIALOG_LIB_EDIT_PIN_TABLE::OnColSort ), nullptr, this );
449 }
450 
451 
453 {
455 
456  // Disconnect Events
457  m_grid->Disconnect( wxEVT_GRID_COL_SORT, wxGridEventHandler( DIALOG_LIB_EDIT_PIN_TABLE::OnColSort ), nullptr, this );
458 
459  // Prevents crash bug in wxGrid's d'tor
461 
462  // Delete the GRID_TRICKS.
463  m_grid->PopEventHandler( true );
464 
465  // This is our copy of the pins. If they were transfered to the part on an OK, then
466  // m_pins will already be empty.
467  for( auto pin : m_pins )
468  delete pin;
469 }
470 
471 
473 {
474  // Make a copy of the pins for editing
475  for( LIB_PIN* pin = m_part->GetNextPin( nullptr ); pin; pin = m_part->GetNextPin( pin ) )
476  m_pins.push_back( new LIB_PIN( *pin ) );
477 
478  m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
479 
480  updateSummary();
481 
482  return true;
483 }
484 
485 
487 {
488  if( !m_grid->CommitPendingChanges() )
489  return false;
490 
491  // Delete the part's pins
492  while( LIB_PIN* pin = m_part->GetNextPin( nullptr ) )
493  m_part->RemoveDrawItem( pin );
494 
495  // Transfer our pins to the part
496  for( LIB_PIN* pin : m_pins )
497  {
498  pin->SetParent( m_part );
499  m_part->AddDrawItem( pin );
500  }
501 
502  m_pins.clear();
503 
504  return true;
505 }
506 
507 
508 void DIALOG_LIB_EDIT_PIN_TABLE::OnColSort( wxGridEvent& aEvent )
509 {
510  int sortCol = aEvent.GetCol();
511  bool ascending;
512 
513  // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
514  // event, and if we ask it will give us pre-event info.
515  if( m_grid->IsSortingBy( sortCol ) )
516  // same column; invert ascending
517  ascending = !m_grid->IsSortOrderAscending();
518  else
519  // different column; start with ascending
520  ascending = true;
521 
522  m_dataModel->SortRows( sortCol, ascending );
523 }
524 
525 
526 void DIALOG_LIB_EDIT_PIN_TABLE::OnAddRow( wxCommandEvent& event )
527 {
528  if( !m_grid->CommitPendingChanges() )
529  return;
530 
531  m_pins.push_back( new LIB_PIN( nullptr ) );
532 
533  m_dataModel->AppendRow( m_pins[ m_pins.size() - 1 ] );
534 
535  m_grid->MakeCellVisible( m_grid->GetNumberRows() - 1, 0 );
536  m_grid->SetGridCursor( m_grid->GetNumberRows() - 1, 0 );
537 
538  m_grid->EnableCellEditControl( true );
539  m_grid->ShowCellEditControl();
540 
541  updateSummary();
542 }
543 
544 
545 void DIALOG_LIB_EDIT_PIN_TABLE::OnDeleteRow( wxCommandEvent& event )
546 {
547  if( !m_grid->CommitPendingChanges() )
548  return;
549 
550  int curRow = m_grid->GetGridCursorRow();
551 
552  if( curRow < 0 )
553  return;
554 
555  LIB_PINS removedRow = m_dataModel->RemoveRow( curRow );
556 
557  for( auto pin : removedRow )
558  m_pins.erase( std::find( m_pins.begin(), m_pins.end(), pin ) );
559 
560  curRow = std::max( 0, curRow - 1 );
561  m_grid->MakeCellVisible( curRow, m_grid->GetGridCursorCol() );
562  m_grid->SetGridCursor( curRow, m_grid->GetGridCursorCol() );
563 
564  updateSummary();
565 }
566 
567 
568 void DIALOG_LIB_EDIT_PIN_TABLE::OnCellEdited( wxGridEvent& event )
569 {
570  updateSummary();
571 }
572 
573 
575 {
576  if( !m_grid->CommitPendingChanges() )
577  return;
578 
579  m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
580 
581  adjustGridColumns( m_grid->GetRect().GetWidth() );
582 }
583 
584 
586 {
587  m_width = aWidth;
588 
589  // Account for scroll bars
590  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
591 
592  wxGridUpdateLocker deferRepaintsTillLeavingScope;
593 
594  // The Number and Name columns must be at least wide enough to hold their contents, but
595  // no less wide than their original widths.
596 
597  m_grid->AutoSizeColumn( COL_NUMBER );
598 
599  if( m_grid->GetColSize( COL_NUMBER ) < m_originalColWidths[ COL_NUMBER ] )
600  m_grid->SetColSize( COL_NUMBER, m_originalColWidths[ COL_NUMBER ] );
601 
602  m_grid->AutoSizeColumn( COL_NAME );
603 
604  if( m_grid->GetColSize( COL_NAME ) < m_originalColWidths[ COL_NAME ] )
605  m_grid->SetColSize( COL_NAME, m_originalColWidths[ COL_NAME ] );
606 
607  // If the grid is still wider than the columns, then stretch the Number and Name columns
608  // to fit.
609 
610  for( int i = 0; i < COL_COUNT; ++i )
611  aWidth -= m_grid->GetColSize( i );
612 
613  if( aWidth > 0 )
614  {
615  m_grid->SetColSize( COL_NUMBER, m_grid->GetColSize( COL_NUMBER ) + aWidth / 2 );
616  m_grid->SetColSize( COL_NAME, m_grid->GetColSize( COL_NAME ) + aWidth / 2 );
617  }
618 }
619 
620 
621 void DIALOG_LIB_EDIT_PIN_TABLE::OnSize( wxSizeEvent& event )
622 {
623  auto new_size = event.GetSize().GetX();
624 
625  if( m_initialized && m_width != new_size )
626  {
627  adjustGridColumns( new_size );
628  event.Skip();
629  }
630 }
631 
632 
633 void DIALOG_LIB_EDIT_PIN_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
634 {
635  wxString columnsShown = m_grid->GetShownColumns();
636 
637  if( columnsShown != m_columnsShown )
638  {
639  m_columnsShown = columnsShown;
640 
641  if( !m_grid->IsCellEditControlShown() )
642  adjustGridColumns( m_grid->GetRect().GetWidth() );
643  }
644 }
645 
646 
647 void DIALOG_LIB_EDIT_PIN_TABLE::OnCancel( wxCommandEvent& event )
648 {
649  Close();
650 }
651 
652 
653 void DIALOG_LIB_EDIT_PIN_TABLE::OnClose( wxCloseEvent& event )
654 {
655  // This is a cancel, so commit quietly as we're going to throw the results away anyway.
656  m_grid->CommitPendingChanges( true );
657 
658  if( m_dataModel->IsEdited() )
659  {
660  if( !HandleUnsavedChanges( this, wxEmptyString,
661  [&]()->bool { return TransferDataFromWindow(); } ) )
662  {
663  event.Veto();
664  return;
665  }
666  }
667 
668  if( IsQuasiModal() )
669  EndQuasiModal( wxID_CANCEL );
670  else if( IsModal() )
671  EndModal( wxID_CANCEL );
672  else
673  event.Skip();
674 }
675 
676 
678 {
679  PinNumbers pinNumbers;
680 
681  for( LIB_PIN* pin : m_pins )
682  {
683  if( pin->GetNumber().Length() )
684  pinNumbers.insert( pin->GetNumber() );
685  }
686 
687  m_summary->SetLabel( pinNumbers.GetSummary() );
688 }
static int Compare(PinNumber const &lhs, PinNumber const &rhs)
Definition: pin_number.cpp:111
static wxArrayString g_typeNames
static std::vector< BITMAP_DEF > g_orientationIcons
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Function HandleUnsavedChanges displays a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:211
void OnClose(wxCloseEvent &event) override
static wxArrayString g_shapeNames
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:313
static std::vector< BITMAP_DEF > g_shapeIcons
void OnSize(wxSizeEvent &event) override
static int GetOrientationIndex(int aCode)
Get the index of the orientation code.
Definition: lib_pin.cpp:1908
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
static wxArrayString GetOrientationNames()
Get a list of pin orientation names.
Definition: lib_pin.cpp:1888
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:119
void OnAddRow(wxCommandEvent &event) override
wxString GetSummary() const
Definition: pin_number.cpp:71
PIN_TABLE_DATA_MODEL(EDA_UNITS_T aUserUnits)
void OnCellEdited(wxGridEvent &event) override
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
Class GRID_TRICKS is used to add mouse and command handling (such as cut, copy, and paste) to a WX_GR...
Definition: grid_tricks.h:51
static const BITMAP_DEF * GetOrientationSymbols()
Get a list of pin orientation bitmaps for menus and dialogs.
Definition: lib_pin.cpp:1950
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:57
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: base_units.cpp:409
void insert(value_type const &v)
Definition: pin_number.h:57
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
DIALOG_LIB_EDIT_PIN_TABLE(wxWindow *parent, LIB_PART *aPart)
void AddDrawItem(LIB_ITEM *aItem)
Add a new draw aItem to the draw object list.
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:88
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
bool m_modified
true when there are unsaved changes
GRAPHIC_PINSHAPE
Definition: pin_shape.h:35
bool IsEmptyCell(int row, int col) override
void SortRows(int aSortCol, bool ascending)
#define INDETERMINATE
void OnRebuildRows(wxCommandEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) override
Define a library symbol object.
bool IsQuasiModal()
Definition: dialog_shim.h:125
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
static wxArrayString g_orientationNames
void RebuildRows(LIB_PINS &aPins, bool groupByName)
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:167
static bool compare(const LIB_PINS &lhs, const LIB_PINS &rhs, int sortCol, bool ascending, EDA_UNITS_T units)
wxString GetColLabelValue(int aCol) override
PIN_TABLE_DATA_MODEL * m_dataModel
wxString GetValue(int aRow, int aCol) override
#define PinTableShownColumnsKey
YYCODETYPE lhs
Class DIALOG_LIB_EDIT_PIN_TABLE_BASE.
LIB_PIN * GetNextPin(LIB_PIN *aItem=NULL)
Return the next pin object from the draw list.
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:101
void EndQuasiModal(int retCode)
static int findRow(const std::vector< LIB_PINS > &aRowSet, const wxString &aName)
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_draw_item.h:61
static wxString GetValue(const LIB_PINS &pins, int aCol, EDA_UNITS_T aUserUnits)
void OnDeleteRow(wxCommandEvent &event) override
ELECTRICAL_PINTYPE
The component library pin object electrical types used in ERC tests.
Definition: pin_type.h:37
#define max(a, b)
Definition: auxiliary.h:86
size_t i
Definition: json11.cpp:597
void RemoveDrawItem(LIB_ITEM *aItem, EDA_DRAW_PANEL *aPanel=NULL, wxDC *aDc=NULL)
Remove draw aItem from list.
void OnColSort(wxGridEvent &aEvent)
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:210
void SetValue(int aRow, int aCol, const wxString &aValue) override
static std::vector< BITMAP_DEF > g_typeIcons
BITMAP_DEF GetBitmap(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:70
std::vector< LIB_PINS > m_rows
void OnCancel(wxCommandEvent &event) override
EDA_UNITS_T
Definition: common.h:160
static int GetOrientationCode(int aIndex)
Get the orientation code by index used to set the pin orientation.
Definition: lib_pin.cpp:1899
EDA_UNITS_T GetUserUnits() const override
Definition: dialog_shim.h:133