KiCad PCB EDA Suite
dialog_fp_lib_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) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2013 CERN
6  * Copyright (C) 2012-2017 KiCad Developers, see change_log.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 
27 /* TODO:
28 
29 *) After any change to uri, reparse the environment variables.
30 
31 */
32 
33 
34 #include <set>
35 #include <wx/regex.h>
36 
37 #include <fctsys.h>
38 #include <project.h>
39 #include <3d_viewer.h> // for KISYS3DMOD
41 #include <fp_lib_table.h>
42 #include <lib_table_lexer.h>
43 #include <invoke_pcb_dialog.h>
44 #include <grid_tricks.h>
45 #include <confirm.h>
46 #include <wizard_add_fplib.h>
47 #include <lib_table_grid.h>
48 
49 
54 {
55  friend class FP_GRID_TRICKS;
56 
57 protected:
58  LIB_TABLE_ROW* at( size_t aIndex ) override { return &rows.at( aIndex ); }
59 
60  size_t size() const override { return rows.size(); }
61 
63  {
64  return dynamic_cast< LIB_TABLE_ROW* >( new FP_LIB_TABLE_ROW );
65  }
66 
67  LIB_TABLE_ROWS_ITER begin() override { return rows.begin(); }
68 
70  {
71  return rows.insert( aIterator, aRow );
72  }
73 
74  void push_back( LIB_TABLE_ROW* aRow ) override { rows.push_back( aRow ); }
75 
77  {
78  return rows.erase( aFirst, aLast );
79  }
80 
81 public:
82 
83  FP_LIB_TABLE_GRID( const FP_LIB_TABLE& aTableToEdit )
84  {
85  rows = aTableToEdit.rows;
86  }
87 };
88 
89 
91 {
92 public:
93  FP_GRID_TRICKS( wxGrid* aGrid ) :
94  GRID_TRICKS( aGrid )
95  {
96  }
97 
98 protected:
99 
102  virtual void paste_text( const wxString& cb_text ) override
103  {
104  FP_LIB_TABLE_GRID* tbl = (FP_LIB_TABLE_GRID*) m_grid->GetTable();
105 
106  size_t ndx = cb_text.find( "(fp_lib_table" );
107 
108  if( ndx != std::string::npos )
109  {
110  // paste the FP_LIB_TABLE_ROWs of s-expression (fp_lib_table), starting
111  // at column 0 regardless of current cursor column.
112 
113  STRING_LINE_READER slr( TO_UTF8( cb_text ), "Clipboard" );
114  LIB_TABLE_LEXER lexer( &slr );
115  FP_LIB_TABLE tmp_tbl;
116  bool parsed = true;
117 
118  try
119  {
120  tmp_tbl.Parse( &lexer );
121  }
122  catch( PARSE_ERROR& pe )
123  {
124  DisplayError( NULL, pe.What() );
125  parsed = false;
126  }
127 
128  if( parsed )
129  {
130  const int cur_row = std::max( getCursorRow(), 0 );
131 
132  // if clipboard rows would extend past end of current table size...
133  if( tmp_tbl.GetCount() > tbl->GetNumberRows() - cur_row )
134  {
135  int newRowsNeeded = tmp_tbl.GetCount() - ( tbl->GetNumberRows() - cur_row );
136  tbl->AppendRows( newRowsNeeded );
137  }
138 
139  for( int i = 0; i < tmp_tbl.GetCount(); ++i )
140  {
141  tbl->rows.replace( cur_row+i, tmp_tbl.At( i ) );
142  }
143  }
144 
145  m_grid->AutoSizeColumns( false );
146  }
147  else
148  {
149  // paste spreadsheet formatted text.
150  GRID_TRICKS::paste_text( cb_text );
151  }
152  }
153 };
154 
155 
162 {
163 
164 public:
165  DIALOG_FP_LIB_TABLE( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) :
166  DIALOG_FP_LIB_TABLE_BASE( aParent ),
167  m_global( aGlobal ),
168  m_project( aProject )
169  {
170  // For user info, shows the table filenames:
171  m_PrjTableFilename->SetLabel( Prj().FootprintLibTblName() );
173 
174  // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
175  // so make it a grid owned table.
176  m_global_grid->SetTable( new FP_LIB_TABLE_GRID( *aGlobal ), true );
177  m_project_grid->SetTable( new FP_LIB_TABLE_GRID( *aProject ), true );
178 
179  // add Cut, Copy, and Paste to wxGrids
180  m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_global_grid ) );
181  m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_project_grid ) );
182 
183  m_global_grid->AutoSizeColumns( false );
184  m_project_grid->AutoSizeColumns( false );
185 
186  wxArrayString choices;
187 
188  choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) );
189  choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
190  choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
191  choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );
192  choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) );
193 
194  /* PCAD_PLUGIN does not support Footprint*() functions
195  choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
196  */
197 
198  wxGridCellAttr* attr;
199 
200  attr = new wxGridCellAttr;
201  attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
202  m_project_grid->SetColAttr( COL_TYPE, attr );
203 
204  attr = new wxGridCellAttr;
205  attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
206  m_global_grid->SetColAttr( COL_TYPE, attr );
207 
209 
210  for( int i=0; i<2; ++i )
211  {
212  wxGrid* g = i==0 ? m_global_grid : m_project_grid;
213 
214  // all but COL_OPTIONS, which is edited with Option Editor anyways.
215  g->AutoSizeColumn( COL_NICKNAME, false );
216  g->AutoSizeColumn( COL_TYPE, false );
217  g->AutoSizeColumn( COL_URI, false );
218  g->AutoSizeColumn( COL_DESCR, false );
219 
220  // would set this to width of title, if it was easily known.
221  g->SetColSize( COL_OPTIONS, 80 );
222  }
223 
224  // This scrunches the dialog hideously, probably due to wxAUI container.
225  // Fit();
226  // We derive from DIALOG_SHIM so prior size will be used anyways.
227 
228  // select the last selected page
229  m_auinotebook->SetSelection( m_pageNdx );
230 
231  // fire pageChangedHandler() so m_cur_grid gets set
232  // m_auinotebook->SetSelection will generate a pageChangedHandler()
233  // event call later, but too late.
234  wxAuiNotebookEvent uneventful;
235  pageChangedHandler( uneventful );
236 
237  // Gives a selection for each grid, mainly for delete lib button.
238  // Without that, we do not see what lib will be deleted
239  m_global_grid->SelectRow( 0 );
240  m_project_grid->SelectRow( 0 );
241 
242  // for ALT+A handling, we want the initial focus to be on the first selected grid.
243  m_cur_grid->SetFocus();
244 
245  // On some windows manager (Unity, XFCE), this dialog is
246  // not always raised, depending on this dialog is run.
247  // Force it to be raised
248  Raise();
249  }
250 
252  {
253  // Delete the GRID_TRICKS.
254  // Any additional event handlers should be popped before the window is deleted.
255  m_global_grid->PopEventHandler( true );
256  m_project_grid->PopEventHandler( true );
257  }
258 
259 
260 private:
263  int getCursorCol() const
264  {
265  return m_cur_grid->GetGridCursorCol();
266  }
267 
270  int getCursorRow() const
271  {
272  return m_cur_grid->GetGridCursorRow();
273  }
274 
281  {
282  for( int t=0; t<2; ++t )
283  {
284  FP_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model();
285 
286  for( int r = 0; r < model.GetNumberRows(); )
287  {
288  wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
289  wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim();
290 
291  if( !nick || !uri )
292  {
293  // Delete the "empty" row, where empty means missing nick or uri.
294  // This also updates the UI which could be slow, but there should only be a few
295  // rows to delete, unless the user fell asleep on the Add Row
296  // button.
297  model.DeleteRows( r, 1 );
298  }
299  else if( nick.find( ':' ) != size_t( -1 ) )
300  {
301  wxString msg = wxString::Format(
302  _( "Illegal character '%s' found in Nickname: '%s' in row %d" ),
303  ":", GetChars( nick ), r );
304 
305  // show the tabbed panel holding the grid we have flunked:
306  if( &model != cur_model() )
307  {
308  m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
309  }
310 
311  // go to the problematic row
312  m_cur_grid->SetGridCursor( r, 0 );
313  m_cur_grid->SelectBlock( r, 0, r, 0 );
314  m_cur_grid->MakeCellVisible( r, 0 );
315 
316  wxMessageDialog errdlg( this, msg, _( "No Colon in Nicknames" ) );
317  errdlg.ShowModal();
318  return false;
319  }
320  else
321  {
322  // set the trimmed values back into the table so they get saved to disk.
323  model.SetValue( r, COL_NICKNAME, nick );
324  model.SetValue( r, COL_URI, uri );
325  ++r; // this row was OK.
326  }
327  }
328  }
329 
330  // check for duplicate nickNames, separately in each table.
331  for( int t=0; t<2; ++t )
332  {
333  FP_LIB_TABLE_GRID& model = t==0 ? *global_model() : *project_model();
334 
335  for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 )
336  {
337  wxString nick1 = model.GetValue( r1, COL_NICKNAME );
338 
339  for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 )
340  {
341  wxString nick2 = model.GetValue( r2, COL_NICKNAME );
342 
343  if( nick1 == nick2 )
344  {
345  wxString msg = wxString::Format(
346  _( "Duplicate Nickname: '%s' in rows %d and %d" ),
347  GetChars( nick1 ), r1+1, r2+1
348  );
349 
350  // show the tabbed panel holding the grid we have flunked:
351  if( &model != cur_model() )
352  {
353  m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
354  }
355 
356  // go to the lower of the two rows, it is technically the duplicate:
357  m_cur_grid->SetGridCursor( r2, 0 );
358  m_cur_grid->SelectBlock( r2, 0, r2, 0 );
359  m_cur_grid->MakeCellVisible( r2, 0 );
360 
361  wxMessageDialog errdlg( this, msg, _( "Please Delete or Modify One" ) );
362  errdlg.ShowModal();
363  return false;
364  }
365  }
366  }
367  }
368 
369  return true;
370  }
371 
372  //-----<event handlers>----------------------------------
373 
374  void onKeyDown( wxKeyEvent& ev ) override
375  {
376 #if 0
377  // send the key to the current grid
378  ((wxEvtHandler*)m_cur_grid)->ProcessEvent( ev );
379 #else
380  // or no:
381  // m_cur_grid has the focus most of the time anyways, so above not needed.
382  ev.Skip();
383 #endif
384  }
385 
386  void pageChangedHandler( wxAuiNotebookEvent& event ) override
387  {
388  m_pageNdx = m_auinotebook->GetSelection();
390  }
391 
392  void appendRowHandler( wxCommandEvent& event ) override
393  {
394  if( m_cur_grid->AppendRows( 1 ) )
395  {
396  int last_row = m_cur_grid->GetNumberRows() - 1;
397 
398  // wx documentation is wrong, SetGridCursor does not make visible.
399  m_cur_grid->MakeCellVisible( last_row, 0 );
400  m_cur_grid->SetGridCursor( last_row, 0 );
401  m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
402  }
403  }
404 
405  void deleteRowHandler( wxCommandEvent& event ) override
406  {
407  int currRow = getCursorRow();
408 
409  // In a wxGrid, collect rows that have a selected cell, or are selected
410  // is not so easy: it depend on the way the selection was made.
411  // Here, we collect row selected by clicking on a row label, and
412  // row that contain a cell previously selected.
413  // If no candidate, just delete the row with the grid cursor.
414  wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
415  wxGridCellCoordsArray cells = m_cur_grid->GetSelectedCells();
416 
417  // Add all row having cell selected to list:
418  for( unsigned ii = 0; ii < cells.GetCount(); ii++ )
419  selectedRows.Add( cells[ii].GetRow() );
420 
421  // Use the row having the grid cursor only if we have no candidate:
422  if( selectedRows.size() == 0 && getCursorRow() >= 0 )
423  selectedRows.Add( getCursorRow() );
424 
425  std::sort( selectedRows.begin(), selectedRows.end() );
426 
427  // Remove selected rows (note: a row can be stored more than once in list)
428  int last_row = -1;
429  for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
430  {
431  int row = selectedRows[ii];
432 
433  if( row != last_row )
434  {
435  last_row = row;
436  m_cur_grid->DeleteRows( row, 1 );
437  }
438  }
439 
440  if( currRow >= m_cur_grid->GetNumberRows() )
441  m_cur_grid->SetGridCursor(m_cur_grid->GetNumberRows()-1, getCursorCol() );
442 
443  m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
444  }
445 
446  void moveUpHandler( wxCommandEvent& event ) override
447  {
448  wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows();
449 
450  if( rowsSelected.GetCount() == 0 )
451  return;
452 
453  // @todo: add multiple selection moves.
454  int curRow = rowsSelected[0];
455 
456  if( curRow >= 1 )
457  {
458  int curCol = getCursorCol();
459 
460  FP_LIB_TABLE_GRID* tbl = cur_model();
461 
462  boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
463  tbl->rows.release( tbl->rows.begin() + curRow );
464 
465  --curRow;
466  tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
467 
468  if( tbl->GetView() )
469  {
470  // fire a msg to cause redrawing
471  wxGridTableMessage msg( tbl,
472  wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
473  curRow,
474  0 );
475 
476  tbl->GetView()->ProcessTableMessage( msg );
477  }
478 
479  m_cur_grid->MakeCellVisible( curRow, curCol );
480  m_cur_grid->SetGridCursor( curRow, curCol );
481  m_cur_grid->SelectRow( getCursorRow() );
482  }
483  }
484 
485  void moveDownHandler( wxCommandEvent& event ) override
486  {
487  wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows();
488 
489  if( rowsSelected.GetCount() == 0 )
490  return;
491 
492  FP_LIB_TABLE_GRID* tbl = cur_model();
493 
494  // @todo: add multiple selection moves.
495  int curRow = rowsSelected[0];
496 
497  if( unsigned( curRow + 1 ) < tbl->rows.size() )
498  {
499  int curCol = getCursorCol();
500 
501  boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
502  tbl->rows.release( tbl->rows.begin() + curRow );
503 
504  ++curRow;
505  tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
506 
507  if( tbl->GetView() )
508  {
509  // fire a msg to cause redrawing
510  wxGridTableMessage msg( tbl,
511  wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
512  curRow - 1,
513  0 );
514 
515  tbl->GetView()->ProcessTableMessage( msg );
516  }
517 
518  m_cur_grid->MakeCellVisible( curRow, curCol );
519  m_cur_grid->SetGridCursor( curRow, curCol );
520  m_cur_grid->SelectRow( getCursorRow() );
521  }
522  }
523 
524  void optionsEditor( wxCommandEvent& event ) override
525  {
526  FP_LIB_TABLE_GRID* tbl = cur_model();
527 
528  if( tbl->GetNumberRows() )
529  {
530  int curRow = getCursorRow();
531  LIB_TABLE_ROW* row = &tbl->rows[curRow];
532 
533  wxString result;
534  const wxString& options = row->GetOptions();
535 
536  InvokePluginOptionsEditor( this, row->GetNickName(), row->GetType(), options, &result );
537 
538  if( options != result )
539  {
540  row->SetOptions( result );
541 
542  // all but options:
543  m_cur_grid->AutoSizeColumn( COL_NICKNAME, false );
544  m_cur_grid->AutoSizeColumn( COL_URI, false );
545  m_cur_grid->AutoSizeColumn( COL_TYPE, false );
546 
547  // On Windows, the grid is not refresh,
548  // so force resfresh after a change
549 #ifdef __WINDOWS__
550  Refresh();
551 #endif
552  }
553  }
554  }
555 
556  void OnClickLibraryWizard( wxCommandEvent& event ) override;
557 
558  void onCancelButtonClick( wxCommandEvent& event ) override
559  {
560  EndModal( 0 );
561  }
562 
563  void onCancelCaptionButtonClick( wxCloseEvent& event ) override
564  {
565  EndModal( 0 );
566  }
567 
568  void onOKButtonClick( wxCommandEvent& event ) override
569  {
570  int dialogRet = 0;
571 
572  // stuff any pending cell editor text into the table.
573  m_cur_grid->SaveEditControlValue();
574 
575  if( verifyTables() )
576  {
577  if( *global_model() != *m_global )
578  {
579  dialogRet |= 1;
580 
581  m_global->Clear();
582  m_global->rows.transfer( m_global->rows.end(), global_model()->rows.begin(),
583  global_model()->rows.end(), global_model()->rows );
584  m_global->reindex();
585  }
586 
587  if( *project_model() != *m_project )
588  {
589  dialogRet |= 2;
590 
591  m_project->Clear();
592  m_project->rows.transfer( m_project->rows.end(), project_model()->rows.begin(),
593  project_model()->rows.end(), project_model()->rows );
594  m_project->reindex();
595  }
596 
597  EndModal( dialogRet );
598  }
599  }
600 
604  {
605  wxRegEx re( ".*?\\$\\{(.+?)\\}.*?", wxRE_ADVANCED );
606  wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
607 
608  std::set< wxString > unique;
609  typedef std::set<wxString>::const_iterator SET_CITER;
610 
611  // clear the table
612  m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );
613 
616 
617  int gblRowCount = gbl->GetNumberRows();
618  int prjRowCount = prj->GetNumberRows();
619  int row;
620 
621  for( row = 0; row < gblRowCount; ++row )
622  {
623  wxString uri = gbl->GetValue( row, COL_URI );
624 
625  while( re.Matches( uri ) )
626  {
627  wxString envvar = re.GetMatch( uri, 1 );
628 
629  // ignore duplicates
630  unique.insert( envvar );
631 
632  // delete the last match and search again
633  uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
634  }
635  }
636 
637  for( row = 0; row < prjRowCount; ++row )
638  {
639  wxString uri = prj->GetValue( row, COL_URI );
640 
641  while( re.Matches( uri ) )
642  {
643  wxString envvar = re.GetMatch( uri, 1 );
644 
645  // ignore duplicates
646  unique.insert( envvar );
647 
648  // delete the last match and search again
649  uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
650  }
651  }
652 
653  // Make sure this special environment variable shows up even if it was
654  // not used yet. It is automatically set by KiCad to the directory holding
655  // the current project.
656  unique.insert( PROJECT_VAR_NAME );
657  unique.insert( FP_LIB_TABLE::GlobalPathEnvVariableName() );
658  // This special environment variable is used to locate 3d shapes
659  unique.insert( KISYS3DMOD );
660 
661  m_path_subs_grid->AppendRows( unique.size() );
662 
663  row = 0;
664 
665  for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row )
666  {
667  wxString evName = *it;
668  wxString evValue;
669 
670  m_path_subs_grid->SetCellValue( row, 0, evName );
671 
672  if( wxGetEnv( evName, &evValue ) )
673  m_path_subs_grid->SetCellValue( row, 1, evValue );
674  }
675 
676  m_path_subs_grid->AutoSizeColumns();
677  }
678 
679  //-----</event handlers>---------------------------------
680 
681  // caller's tables are modified only on OK button and successful verification.
684 
686  {
687  return (FP_LIB_TABLE_GRID*) m_global_grid->GetTable();
688  }
689 
691  {
692  return (FP_LIB_TABLE_GRID*) m_project_grid->GetTable();
693  }
694 
696  {
697  return (FP_LIB_TABLE_GRID*) m_cur_grid->GetTable();
698  }
699 
700  wxGrid* m_cur_grid;
701  static int m_pageNdx;
702 };
703 
704 
706 
707 
708 void DIALOG_FP_LIB_TABLE::OnClickLibraryWizard( wxCommandEvent& event )
709 {
710  WIZARD_FPLIB_TABLE dlg( this );
711 
712  if( !dlg.RunWizard( dlg.GetFirstPage() ) )
713  return; // Aborted by user
714 
715  const std::vector<WIZARD_FPLIB_TABLE::LIBRARY>& libs = dlg.GetLibraries();
716  bool global_scope = dlg.GetLibScope() == WIZARD_FPLIB_TABLE::GLOBAL;
717  wxGrid* libgrid = global_scope ? m_global_grid : m_project_grid;
718  FP_LIB_TABLE_GRID* tbl = (FP_LIB_TABLE_GRID*) libgrid->GetTable();
719 
720  for( std::vector<WIZARD_FPLIB_TABLE::LIBRARY>::const_iterator it = libs.begin();
721  it != libs.end(); ++it )
722  {
723  if( it->GetStatus() == WIZARD_FPLIB_TABLE::LIBRARY::INVALID )
724  continue;
725 
726  if( libgrid->AppendRows( 1 ) )
727  {
728  int last_row = libgrid->GetNumberRows() - 1;
729 
730  // Add the nickname: currently make it from filename
731  tbl->SetValue( last_row, COL_NICKNAME, it->GetDescription() );
732 
733  // Add the path:
734  tbl->SetValue( last_row, COL_URI, it->GetAutoPath( dlg.GetLibScope() ) );
735 
736  // Add the plugin name:
737  tbl->SetValue( last_row, COL_TYPE, it->GetPluginName() );
738 
739  libgrid->MakeCellVisible( last_row, 0 );
740  libgrid->SetGridCursor( last_row, 0 );
741  }
742  }
743 
744  // Switch to the current scope tab
745  if( global_scope )
746  m_auinotebook->SetSelection( 0 );
747  else
748  m_auinotebook->SetSelection( 1 );
749 
750  libgrid->SelectRow( libgrid->GetGridCursorRow() );
751 }
752 
753 
754 int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal,
755  FP_LIB_TABLE* aProject )
756 {
757  DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject );
758 
759  int dialogRet = dlg.ShowModal(); // returns value passed to EndModal() above
760 
761  return dialogRet;
762 }
763 
764 
765 int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal,
766  FP_LIB_TABLE* aProject )
767 {
768  WIZARD_FPLIB_TABLE dlg( aParent );
769 
770  if( !dlg.RunWizard( dlg.GetFirstPage() ) )
771  return 0; // Aborted by user
772 
773  const std::vector<WIZARD_FPLIB_TABLE::LIBRARY>& libs = dlg.GetLibraries();
775  FP_LIB_TABLE* fp_tbl = ( scope == WIZARD_FPLIB_TABLE::GLOBAL ? aGlobal : aProject );
776 
777  if( fp_tbl )
778  {
779  for( std::vector<WIZARD_FPLIB_TABLE::LIBRARY>::const_iterator it = libs.begin();
780  it != libs.end(); ++it )
781  {
782  if( it->GetStatus() == WIZARD_FPLIB_TABLE::LIBRARY::INVALID )
783  continue;
784 
785  FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( it->GetDescription(),
786  it->GetAutoPath( scope ),
787  it->GetPluginName(),
788  wxEmptyString ); // options
789  fp_tbl->InsertRow( row );
790  }
791  }
792 
793  return scope;
794 }
int GetCount()
FP_LIB_TABLE_GRID * project_model() const
int getCursorCol() const
If the cursor is not on a valid cell, because there are no rows at all, return -1, else return a 0 based column index.
wxGrid * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:42
void push_back(LIB_TABLE_ROW *aRow) override
int getCursorRow() const
If the cursor is not on a valid cell, because there are no rows at all, return -1, else return a 0 based row index.
Class LIB_TABLE_ROW.
void Clear()
Delete all rows.
LIB_SCOPE GetLibScope() const
Function GetLibScope Returns the scope for the added libraries (global / project specific).
void OnClickLibraryWizard(wxCommandEvent &event) override
void appendRowHandler(wxCommandEvent &event) override
Class FP_LIB_TABLE_ROW.
Definition: fp_lib_table.h:42
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Function InsertRow.
This file is part of the common library.
void reindex()
void onCancelCaptionButtonClick(wxCloseEvent &event) override
void InvokePluginOptionsEditor(wxTopLevelWindow *aCaller, const wxString &aNickname, const wxString &aPluginType, const wxString &aOptions, wxString *aResult)
Function InvokePluginOptionsEditor calls DIALOG_FP_PLUGIN_OPTIONS dialog so that plugin options set c...
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:32
Class GRID_TRICKS is used to add cut, copy, and paste to an otherwise unmodied wxGrid instance...
Definition: grid_tricks.h:34
void deleteRowHandler(wxCommandEvent &event) override
bool DeleteRows(size_t aPos, size_t aNumRows) override
Class DIALOG_FP_LIB_TABLE shows and edits the PCB library tables.
const wxString & GetOptions() const
Function GetOptions.
LIB_TABLE_ROW * At(int aIndex)
LIB_TABLE_ROWS rows
void moveUpHandler(wxCommandEvent &event) override
static const wxString ShowType(PCB_FILE_T aFileType)
Function ShowType returns a brief name for a plugin, given aFileType enum.
Definition: io_mgr.cpp:105
virtual const wxString GetType() const =0
Function GetType.
int InvokeFootprintWizard(wxTopLevelWindow *aParent, FP_LIB_TABLE *aGlobal, FP_LIB_TABLE *aProject)
Function InvokeFootprintWizard Runs the footprint library wizard for easy library addition...
int GetNumberRows() override
void moveDownHandler(wxCommandEvent &event) override
Geda PCB file formats.
Definition: io_mgr.h:57
size_t size() const override
FP_LIB_TABLE_GRID * global_model() const
void populateEnvironReadOnlyTable()
Populate the readonly environment variable table with names and values by examining all the full_uri ...
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
LIB_TABLE_ROWS_ITER insert(LIB_TABLE_ROWS_ITER aIterator, LIB_TABLE_ROW *aRow) override
virtual void paste_text(const wxString &cb_text)
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
static const wxString GlobalPathEnvVariableName()
Function GlobalPathEnvVarVariableName.
virtual void paste_text(const wxString &cb_text) override
handle specialized clipboard text, with leading "(fp_lib_table", OR spreadsheet formatted text...
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Function Parse.
int InvokePcbLibTableEditor(wxTopLevelWindow *aParent, FP_LIB_TABLE *aGlobal, FP_LIB_TABLE *aProject)
Function InvokePcbLibTableEditor shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib ...
void Refresh()
LIB_SCOPE
Scope (global/project)
S-expression Pcbnew file format.
Definition: io_mgr.h:54
#define KISYS3DMOD
A variable name whose value holds the path of 3D shape files.
Definition: 3d_viewer.h:38
void pageChangedHandler(wxAuiNotebookEvent &event) override
const std::vector< LIBRARY > & GetLibraries() const
Function GetLibraries Returns libraries selected by the user.
bool AppendRows(size_t aNumRows=1) override
FP_LIB_TABLE_GRID * cur_model() const
DIALOG_FP_LIB_TABLE(wxTopLevelWindow *aParent, FP_LIB_TABLE *aGlobal, FP_LIB_TABLE *aProject)
void onKeyDown(wxKeyEvent &ev) override
LIB_TABLE_ROWS_ITER begin() override
Class DIALOG_FP_LIB_TABLE_BASE.
int getCursorRow() const
If the cursor is not on a valid cell, because there are no rows at all, return -1, else return a 0 based row index.
Definition: grid_tricks.h:60
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxString GetValue(int aRow, int aCol) override
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
const wxString & GetNickName() const
Function GetNickName.
Struct PARSE_ERROR contains a filename or source description, a problem input line, a line number, a byte offset, and an error message which contains the the caller's report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:53
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
LIB_TABLE_ROW * makeNewRow() override
#define max(a, b)
Definition: auxiliary.h:86
FP_LIB_TABLE_GRID(const FP_LIB_TABLE &aTableToEdit)
wxWizardPage * GetFirstPage() const
Function GetFirstPage Returns the welcoming page for the wizard.
static int m_pageNdx
Remember the last notebook page selected during a session.
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
LIB_TABLE_ROWS_ITER erase(LIB_TABLE_ROWS_ITER aFirst, LIB_TABLE_ROWS_ITER aLast) override
FP_GRID_TRICKS(wxGrid *aGrid)
wxGrid * m_cur_grid
changed based on tab choice
This class builds a wxGridTableBase by wrapping an FP_LIB_TABLE object.
Class LIB_TABLE_LEXER is an automatically generated class using the TokenList2DnsLexer.cmake technology, based on keywords provided by file: /home/kicad/workspace/kicad-doxygen/common/lib_table.keywords.
void SetOptions(const wxString &aOptions)
Function SetOptions.
void onOKButtonClick(wxCommandEvent &event) override
void onCancelButtonClick(wxCommandEvent &event) override
bool verifyTables()
Function verifyTables trims important fields, removes blank row entries, and checks for duplicates...
Class STRING_LINE_READER is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:254
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
Read only http://github.com repo holding pretty footprints.
Definition: io_mgr.h:58
LIB_TABLE_ROW * at(size_t aIndex) override
Declaration of the eda_3d_viewer class.
static wxString GetGlobalTableFileName()
Function GetGlobalTableFileName.
void optionsEditor(wxCommandEvent &event) override