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 #include <lib_edit_frame.h>
38 
39 #define PinTableShownColumnsKey wxT( "PinTableShownColumns" )
40 
41 
42 static std::vector<BITMAP_DEF> g_typeIcons;
43 static wxArrayString g_typeNames;
44 
45 static std::vector<BITMAP_DEF> g_shapeIcons;
46 static wxArrayString g_shapeNames;
47 
48 static std::vector<BITMAP_DEF> g_orientationIcons;
49 static wxArrayString g_orientationNames;
50 
51 
52 class PIN_TABLE_DATA_MODEL : public wxGridTableBase
53 {
54 
55 private:
56  // Because the rows of the grid can either be a single pin or a group of pins, the
57  // data model is a 2D vector. If we're in the single pin case, each row's LIB_PINS
58  // contains only a single pin.
59  std::vector<LIB_PINS> m_rows;
60 
62  bool m_edited;
63 
64 public:
66  m_userUnits( aUserUnits ), m_edited( false )
67  {}
68 
69  int GetNumberRows() override { return (int) m_rows.size(); }
70  int GetNumberCols() override { return COL_COUNT; }
71 
72  wxString GetColLabelValue( int aCol ) override
73  {
74  switch( aCol )
75  {
76  case COL_NUMBER: return _( "Number" );
77  case COL_NAME: return _( "Name" );
78  case COL_TYPE: return _( "Electrical Type" );
79  case COL_SHAPE: return _( "Graphic Style" );
80  case COL_ORIENTATION: return _( "Orientation" );
81  case COL_NUMBER_SIZE: return _( "Number Text Size" );
82  case COL_NAME_SIZE: return _( "Name Text Size" );
83  case COL_LENGTH: return _( "Length" );
84  case COL_POSX: return _( "X Position" );
85  case COL_POSY: return _( "Y Position" );
86  default: wxFAIL; return wxEmptyString;
87  }
88  }
89 
90  bool IsEmptyCell( int row, int col ) override
91  {
92  return false; // don't allow adjacent cell overflow, even if we are actually empty
93  }
94 
95  wxString GetValue( int aRow, int aCol ) override
96  {
97  return GetValue( m_rows[ aRow ], aCol, m_userUnits );
98  }
99 
100  static wxString GetValue( const LIB_PINS& pins, int aCol, EDA_UNITS_T aUserUnits )
101  {
102  wxString fieldValue;
103 
104  if( pins.empty())
105  return fieldValue;
106 
107  for( LIB_PIN* pin : pins )
108  {
109  wxString val;
110 
111  switch( aCol )
112  {
113  case COL_NUMBER:
114  val = pin->GetNumber();
115  break;
116  case COL_NAME:
117  val = pin->GetName();
118  break;
119  case COL_TYPE:
120  val = g_typeNames[ pin->GetType() ];
121  break;
122  case COL_SHAPE:
123  val = g_shapeNames[ pin->GetShape() ];
124  break;
125  case COL_ORIENTATION:
126  val = g_orientationNames[ LIB_PIN::GetOrientationIndex( pin->GetOrientation() ) ];
127  break;
128  case COL_NUMBER_SIZE:
129  val = StringFromValue( aUserUnits, pin->GetNumberTextSize(), true, true );
130  break;
131  case COL_NAME_SIZE:
132  val = StringFromValue( aUserUnits, pin->GetNameTextSize(), true, true );
133  break;
134  case COL_LENGTH:
135  val = StringFromValue( aUserUnits, pin->GetLength(), true );
136  break;
137  case COL_POSX:
138  val = StringFromValue( aUserUnits, pin->GetPosition().x, true );
139  break;
140  case COL_POSY:
141  val = StringFromValue( aUserUnits, pin->GetPosition().y, true );
142  break;
143  default:
144  wxFAIL;
145  break;
146  }
147 
148  if( aCol == COL_NUMBER )
149  {
150  if( fieldValue.length() )
151  fieldValue += wxT( ", " );
152  fieldValue += val;
153  }
154  else
155  {
156  if( !fieldValue.Length() )
157  fieldValue = val;
158  else if( val != fieldValue )
159  fieldValue = INDETERMINATE;
160  }
161  }
162 
163  return fieldValue;
164  }
165 
166  void SetValue( int aRow, int aCol, const wxString &aValue ) override
167  {
168  if( aValue == INDETERMINATE )
169  return;
170 
171  LIB_PINS pins = m_rows[ aRow ];
172 
173  for( LIB_PIN* pin : pins )
174  {
175  switch( aCol )
176  {
177  case COL_NUMBER:
178  pin->SetNumber( aValue );
179  break;
180  case COL_NAME:
181  pin->SetName( aValue );
182  break;
183  case COL_TYPE:
184  if( g_typeNames.Index( aValue ) != wxNOT_FOUND )
185  pin->SetType( (ELECTRICAL_PINTYPE) g_typeNames.Index( aValue ), false );
186 
187  break;
188  case COL_SHAPE:
189  if( g_shapeNames.Index( aValue ) != wxNOT_FOUND )
190  pin->SetShape( (GRAPHIC_PINSHAPE) g_shapeNames.Index( aValue ) );
191 
192  break;
193  case COL_ORIENTATION:
194  if( g_orientationNames.Index( aValue ) != wxNOT_FOUND )
195  pin->SetOrientation( LIB_PIN::GetOrientationCode(
196  g_orientationNames.Index( aValue ) ), false );
197  break;
198  case COL_NUMBER_SIZE:
199  pin->SetNumberTextSize( ValueFromString( m_userUnits, aValue, true ) );
200  break;
201  case COL_NAME_SIZE:
202  pin->SetNameTextSize( ValueFromString( m_userUnits, aValue, true ) );
203  break;
204  case COL_LENGTH:
205  pin->SetLength( ValueFromString( m_userUnits, aValue ) );
206  break;
207  case COL_POSX:
208  pin->SetPinPosition( wxPoint( ValueFromString( m_userUnits, aValue ),
209  pin->GetPosition().y ) );
210  break;
211  case COL_POSY:
212  pin->SetPinPosition( wxPoint( pin->GetPosition().x,
213  ValueFromString( m_userUnits, aValue ) ) );
214  break;
215  default:
216  wxFAIL;
217  break;
218  }
219  }
220 
221  m_edited = true;
222  }
223 
224  static int findRow( const std::vector<LIB_PINS>& aRowSet, const wxString& aName )
225  {
226  for( size_t i = 0; i < aRowSet.size(); ++i )
227  {
228  if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
229  return i;
230  }
231 
232  return -1;
233  }
234 
235  static bool compare( const LIB_PINS& lhs, const LIB_PINS& rhs,
236  int sortCol, bool ascending, EDA_UNITS_T units )
237  {
238  wxString lhStr = GetValue( lhs, sortCol, units );
239  wxString rhStr = GetValue( rhs, sortCol, units );
240 
241  if( lhStr == rhStr )
242  {
243  // Secondary sort key is always COL_NUMBER
244  sortCol = COL_NUMBER;
245  lhStr = GetValue( lhs, sortCol, units );
246  rhStr = GetValue( rhs, sortCol, units );
247  }
248 
249  bool cmp;
250 
251  switch( sortCol )
252  {
253  case COL_NUMBER:
254  case COL_NAME:
255  cmp = PinNumbers::Compare( lhStr, rhStr ) < 0;
256  break;
257  case COL_NUMBER_SIZE:
258  case COL_NAME_SIZE:
259  cmp = ValueFromString( units, lhStr, true ) < ValueFromString( units, rhStr, true );
260  break;
261  case COL_LENGTH:
262  case COL_POSX:
263  case COL_POSY:
264  cmp = ValueFromString( units, lhStr ) < ValueFromString( units, rhStr );
265  break;
266  default:
267  cmp = StrNumCmp( lhStr, rhStr ) < 0;
268  break;
269  }
270 
271  return ascending == cmp;
272  }
273 
274  void RebuildRows( LIB_PINS& aPins, bool groupByName )
275  {
276  if ( GetView() )
277  {
278  // Commit any pending in-place edits before the row gets moved out from under
279  // the editor.
280  dynamic_cast<WX_GRID*>( GetView() )->CommitPendingChanges( true );
281 
282  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, m_rows.size() );
283  GetView()->ProcessTableMessage( msg );
284  }
285 
286  m_rows.clear();
287 
288  for( LIB_PIN* pin : aPins )
289  {
290  int rowIndex = -1;
291 
292  if( groupByName )
293  rowIndex = findRow( m_rows, pin->GetName() );
294 
295  if( rowIndex < 0 )
296  {
297  m_rows.emplace_back( LIB_PINS() );
298  rowIndex = m_rows.size() - 1;
299  }
300 
301  m_rows[ rowIndex ].push_back( pin );
302  }
303 
304  int sortCol = 0;
305  bool ascending = true;
306 
307  if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
308  {
309  sortCol = GetView()->GetSortingColumn();
310  ascending = GetView()->IsSortOrderAscending();
311  }
312 
313  SortRows( sortCol, ascending );
314 
315  if ( GetView() )
316  {
317  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_rows.size() );
318  GetView()->ProcessTableMessage( msg );
319  }
320  }
321 
322  void SortRows( int aSortCol, bool ascending )
323  {
324  std::sort( m_rows.begin(), m_rows.end(),
325  [ aSortCol, ascending, this ]( LIB_PINS lhs, LIB_PINS rhs ) -> bool
326  { return compare( lhs, rhs, aSortCol, ascending, m_userUnits ); } );
327  }
328 
329  void AppendRow( LIB_PIN* aPin )
330  {
331  LIB_PINS row;
332  row.push_back( aPin );
333  m_rows.push_back( row );
334 
335  if ( GetView() )
336  {
337  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
338  GetView()->ProcessTableMessage( msg );
339  }
340  }
341 
342  LIB_PINS RemoveRow( int aRow )
343  {
344  LIB_PINS removedRow = m_rows[ aRow ];
345 
346  m_rows.erase( m_rows.begin() + aRow );
347 
348  if ( GetView() )
349  {
350  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
351  GetView()->ProcessTableMessage( msg );
352  }
353 
354  return removedRow;
355  }
356 
357  bool IsEdited()
358  {
359  return m_edited;
360  }
361 };
362 
363 
366  m_editFrame( parent ),
367  m_part( aPart )
368 {
370 
371  if( g_typeNames.empty())
372  {
373  for( unsigned i = 0; i < PINTYPE_COUNT; ++i )
374  g_typeIcons.push_back( GetBitmap( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
375  for( unsigned i = 0; i < PINTYPE_COUNT; ++i )
376  g_typeNames.push_back( GetText( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
377  g_typeNames.push_back( INDETERMINATE );
378 
379  for( unsigned i = 0; i < PINSHAPE_COUNT; ++i )
380  g_shapeIcons.push_back( GetBitmap( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
381  for( unsigned i = 0; i < PINSHAPE_COUNT; ++i )
382  g_shapeNames.push_back( GetText( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
383  g_shapeNames.push_back( INDETERMINATE );
384 
385  for( unsigned i = 0; i < LIB_PIN::GetOrientationNames().size(); ++i )
388  g_orientationNames.push_back( INDETERMINATE );
389  }
390 
392 
393  // Save original columns widths so we can do proportional sizing.
394  for( int i = 0; i < COL_COUNT; ++i )
395  m_originalColWidths[ i ] = m_grid->GetColSize( i );
396 
397  // Give a bit more room for combobox editors
398  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
399 
401  m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
402 
403  // Show/hide columns according to the user's preference
404  m_config->Read( PinTableShownColumnsKey, &m_columnsShown, wxT( "0 1 2 3 4 8 9" ) );
406 
407  // Set special attributes
408  wxGridCellAttr* attr;
409 
410  attr = new wxGridCellAttr;
411  attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_typeIcons, g_typeNames ) );
412  attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_typeIcons, g_typeNames ) );
413  m_grid->SetColAttr( COL_TYPE, attr );
414 
415  attr = new wxGridCellAttr;
416  attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_shapeIcons, g_shapeNames ) );
417  attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_shapeIcons, g_shapeNames ) );
418  m_grid->SetColAttr( COL_SHAPE, attr );
419 
420  attr = new wxGridCellAttr;
423  m_grid->SetColAttr( COL_ORIENTATION, attr );
424 
425  /* Right-aligned position values look much better, but only MSW and GTK2+
426  * currently support righ-aligned textEditCtrls, so the text jumps on all
427  * the other platforms when you edit it.
428  attr = new wxGridCellAttr;
429  attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_TOP );
430  m_grid->SetColAttr( COL_POSX, attr );
431 
432  attr = new wxGridCellAttr;
433  attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_TOP );
434  m_grid->SetColAttr( COL_POSY, attr );
435  */
436 
437  m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
438  m_deleteButton->SetBitmap( KiBitmap( trash_xpm ) );
439  m_refreshButton->SetBitmap( KiBitmap( refresh_xpm ) );
440 
441  GetSizer()->SetSizeHints(this);
442  Centre();
443 
444  m_ButtonsOK->SetDefault();
445  m_initialized = true;
446  m_modified = false;
447  m_width = 0;
448 
449  // Connect Events
450  m_grid->Connect( wxEVT_GRID_COL_SORT, wxGridEventHandler( DIALOG_LIB_EDIT_PIN_TABLE::OnColSort ), nullptr, this );
451 }
452 
453 
455 {
457 
458  // Disconnect Events
459  m_grid->Disconnect( wxEVT_GRID_COL_SORT, wxGridEventHandler( DIALOG_LIB_EDIT_PIN_TABLE::OnColSort ), nullptr, this );
460 
461  // Prevents crash bug in wxGrid's d'tor
463 
464  // Delete the GRID_TRICKS.
465  m_grid->PopEventHandler( true );
466 
467  // This is our copy of the pins. If they were transfered to the part on an OK, then
468  // m_pins will already be empty.
469  for( auto pin : m_pins )
470  delete pin;
471 }
472 
473 
475 {
476  // Make a copy of the pins for editing
477  for( LIB_PIN* pin = m_part->GetNextPin( nullptr ); pin; pin = m_part->GetNextPin( pin ) )
478  m_pins.push_back( new LIB_PIN( *pin ) );
479 
480  m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
481 
482  updateSummary();
483 
484  return true;
485 }
486 
487 
489 {
490  if( !m_grid->CommitPendingChanges() )
491  return false;
492 
493  // Delete the part's pins
494  while( LIB_PIN* pin = m_part->GetNextPin( nullptr ) )
495  m_part->RemoveDrawItem( pin );
496 
497  // Transfer our pins to the part
498  for( LIB_PIN* pin : m_pins )
499  {
500  pin->SetParent( m_part );
501  m_part->AddDrawItem( pin );
502  }
503 
504  m_pins.clear();
505 
506  return true;
507 }
508 
509 
510 void DIALOG_LIB_EDIT_PIN_TABLE::OnColSort( wxGridEvent& aEvent )
511 {
512  int sortCol = aEvent.GetCol();
513  bool ascending;
514 
515  // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
516  // event, and if we ask it will give us pre-event info.
517  if( m_grid->IsSortingBy( sortCol ) )
518  // same column; invert ascending
519  ascending = !m_grid->IsSortOrderAscending();
520  else
521  // different column; start with ascending
522  ascending = true;
523 
524  m_dataModel->SortRows( sortCol, ascending );
525 }
526 
527 
528 void DIALOG_LIB_EDIT_PIN_TABLE::OnAddRow( wxCommandEvent& event )
529 {
530  if( !m_grid->CommitPendingChanges() )
531  return;
532 
533  LIB_PIN* newPin = new LIB_PIN( nullptr );
534 
535  if( m_pins.size() > 0 )
536  {
537  LIB_PIN* last = m_pins.back();
538 
539  newPin->SetOrientation( last->GetOrientation() );
540  newPin->SetType( last->GetType() );
541  newPin->SetShape( last->GetShape() );
542 
543  wxPoint pos = last->GetPosition();
544 
545  if( last->GetOrientation() == PIN_LEFT || last->GetOrientation() == PIN_RIGHT )
546  pos.y -= m_editFrame->GetRepeatPinStep();
547  else
548  pos.x += m_editFrame->GetRepeatPinStep();
549 
550  newPin->SetPosition( pos );
551  }
552 
553  m_pins.push_back( newPin );
554 
555  m_dataModel->AppendRow( m_pins[ m_pins.size() - 1 ] );
556 
557  m_grid->MakeCellVisible( m_grid->GetNumberRows() - 1, 0 );
558  m_grid->SetGridCursor( m_grid->GetNumberRows() - 1, 0 );
559 
560  m_grid->EnableCellEditControl( true );
561  m_grid->ShowCellEditControl();
562 
563  updateSummary();
564 }
565 
566 
567 void DIALOG_LIB_EDIT_PIN_TABLE::OnDeleteRow( wxCommandEvent& event )
568 {
569  if( !m_grid->CommitPendingChanges() )
570  return;
571 
572  if( m_pins.size() == 0 ) // empty table
573  return;
574 
575  int curRow = m_grid->GetGridCursorRow();
576 
577  if( curRow < 0 )
578  return;
579 
580  LIB_PINS removedRow = m_dataModel->RemoveRow( curRow );
581 
582  for( auto pin : removedRow )
583  m_pins.erase( std::find( m_pins.begin(), m_pins.end(), pin ) );
584 
585  curRow = std::max( 0, curRow - 1 );
586  m_grid->MakeCellVisible( curRow, m_grid->GetGridCursorCol() );
587  m_grid->SetGridCursor( curRow, m_grid->GetGridCursorCol() );
588 
589  updateSummary();
590 }
591 
592 
593 void DIALOG_LIB_EDIT_PIN_TABLE::OnCellEdited( wxGridEvent& event )
594 {
595  updateSummary();
596 }
597 
598 
600 {
601  if( !m_grid->CommitPendingChanges() )
602  return;
603 
604  m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
605 
606  adjustGridColumns( m_grid->GetRect().GetWidth() );
607 }
608 
609 
611 {
612  m_width = aWidth;
613 
614  // Account for scroll bars
615  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
616 
617  wxGridUpdateLocker deferRepaintsTillLeavingScope;
618 
619  // The Number and Name columns must be at least wide enough to hold their contents, but
620  // no less wide than their original widths.
621 
622  m_grid->AutoSizeColumn( COL_NUMBER );
623 
624  if( m_grid->GetColSize( COL_NUMBER ) < m_originalColWidths[ COL_NUMBER ] )
625  m_grid->SetColSize( COL_NUMBER, m_originalColWidths[ COL_NUMBER ] );
626 
627  m_grid->AutoSizeColumn( COL_NAME );
628 
629  if( m_grid->GetColSize( COL_NAME ) < m_originalColWidths[ COL_NAME ] )
630  m_grid->SetColSize( COL_NAME, m_originalColWidths[ COL_NAME ] );
631 
632  // If the grid is still wider than the columns, then stretch the Number and Name columns
633  // to fit.
634 
635  for( int i = 0; i < COL_COUNT; ++i )
636  aWidth -= m_grid->GetColSize( i );
637 
638  if( aWidth > 0 )
639  {
640  m_grid->SetColSize( COL_NUMBER, m_grid->GetColSize( COL_NUMBER ) + aWidth / 2 );
641  m_grid->SetColSize( COL_NAME, m_grid->GetColSize( COL_NAME ) + aWidth / 2 );
642  }
643 }
644 
645 
646 void DIALOG_LIB_EDIT_PIN_TABLE::OnSize( wxSizeEvent& event )
647 {
648  auto new_size = event.GetSize().GetX();
649 
650  if( m_initialized && m_width != new_size )
651  {
652  adjustGridColumns( new_size );
653  }
654 
655  // Always propagate for a grid repaint (needed if the height changes, as well as width)
656  event.Skip();
657 }
658 
659 
660 void DIALOG_LIB_EDIT_PIN_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
661 {
662  wxString columnsShown = m_grid->GetShownColumns();
663 
664  if( columnsShown != m_columnsShown )
665  {
666  m_columnsShown = columnsShown;
667 
668  if( !m_grid->IsCellEditControlShown() )
669  adjustGridColumns( m_grid->GetRect().GetWidth() );
670  }
671 }
672 
673 
674 void DIALOG_LIB_EDIT_PIN_TABLE::OnCancel( wxCommandEvent& event )
675 {
676  Close();
677 }
678 
679 
680 void DIALOG_LIB_EDIT_PIN_TABLE::OnClose( wxCloseEvent& event )
681 {
682  // This is a cancel, so commit quietly as we're going to throw the results away anyway.
683  m_grid->CommitPendingChanges( true );
684 
685  if( m_dataModel->IsEdited() )
686  {
687  if( !HandleUnsavedChanges( this, wxEmptyString,
688  [&]()->bool { return TransferDataFromWindow(); } ) )
689  {
690  event.Veto();
691  return;
692  }
693  }
694 
695  if( IsQuasiModal() )
696  EndQuasiModal( wxID_CANCEL );
697  else if( IsModal() )
698  EndModal( wxID_CANCEL );
699  else
700  event.Skip();
701 }
702 
703 
705 {
706  PinNumbers pinNumbers;
707 
708  for( LIB_PIN* pin : m_pins )
709  {
710  if( pin->GetNumber().Length() )
711  pinNumbers.insert( pin->GetNumber() );
712  }
713 
714  m_summary->SetLabel( pinNumbers.GetSummary() );
715 }
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:212
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:342
static std::vector< BITMAP_DEF > g_shapeIcons
void OnSize(wxSizeEvent &event) override
void SetPosition(const wxPoint &aPosition)
static int GetOrientationIndex(int aCode)
Get the index of the orientation code.
Definition: lib_pin.cpp:1624
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:1604
int GetOrientation() const
Definition: lib_pin.h:205
DIALOG_LIB_EDIT_PIN_TABLE(LIB_EDIT_FRAME *parent, LIB_PART *aPart)
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 SetShape(GRAPHIC_PINSHAPE aShape)
Set the shape of the pin to aShape.
Definition: lib_pin.cpp:299
GRAPHIC_PINSHAPE GetShape() const
Definition: lib_pin.h:219
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:1655
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
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
wxPoint GetPosition() const override
Return the current draw object position.
Definition: lib_pin.h:432
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
ELECTRICAL_PINTYPE GetType() const
Get the electrical type of the pin.
Definition: lib_pin.h:235
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
The symbol library editor main window.
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 SetType(ELECTRICAL_PINTYPE aType, bool aTestOtherPins=true)
Set the electrical type of the pin.
Definition: lib_pin.cpp:328
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
void SetOrientation(int aOrientation, bool aTestOtherPins=true)
Set orientation on the pin.
Definition: lib_pin.cpp:270
static std::vector< BITMAP_DEF > g_typeIcons
BITMAP_DEF GetBitmap(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:70
int GetRepeatPinStep() const
std::vector< LIB_PINS > m_rows
void OnCancel(wxCommandEvent &event) override
EDA_UNITS_T
Definition: common.h:157
static int GetOrientationCode(int aIndex)
Get the orientation code by index used to set the pin orientation.
Definition: lib_pin.cpp:1615
EDA_UNITS_T GetUserUnits() const override
Definition: dialog_shim.h:133