KiCad PCB EDA Suite
PANEL_SYM_LIB_TABLE Class Reference

Dialog to show and edit symbol library tables. More...

#include <panel_sym_lib_table.h>

Inheritance diagram for PANEL_SYM_LIB_TABLE:
PANEL_SYM_LIB_TABLE_BASE

Public Member Functions

 PANEL_SYM_LIB_TABLE (DIALOG_EDIT_LIBRARY_TABLES *aParent, PROJECT *m_project, SYMBOL_LIB_TABLE *aGlobal, const wxString &aGlobalTablePath, SYMBOL_LIB_TABLE *aProject, const wxString &aProjectTablePath)
 
virtual ~PANEL_SYM_LIB_TABLE ()
 

Protected Attributes

wxNotebook * m_notebook
 
wxPanel * m_global_panel
 
WX_GRIDm_global_grid
 
wxPanel * m_project_panel
 
WX_GRIDm_project_grid
 
wxBitmapButton * m_append_button
 
wxBitmapButton * m_browse_button
 
wxBitmapButton * m_move_up_button
 
wxBitmapButton * m_move_down_button
 
wxBitmapButton * m_delete_button
 
wxButton * m_convertLegacy
 
WX_GRIDm_path_subs_grid
 

Private Member Functions

bool verifyTables ()
 Trim important fields, removes blank row entries, and checks for duplicates. More...
 
void OnUpdateUI (wxUpdateUIEvent &event) override
 
void browseLibrariesHandler (wxCommandEvent &event) override
 
void appendRowHandler (wxCommandEvent &event) override
 
void deleteRowHandler (wxCommandEvent &event) override
 
void moveUpHandler (wxCommandEvent &event) override
 
void moveDownHandler (wxCommandEvent &event) override
 
void onSizeGrid (wxSizeEvent &event) override
 
void adjustPathSubsGridColumns (int aWidth)
 
void onConvertLegacyLibraries (wxCommandEvent &event) override
 
bool TransferDataFromWindow () override
 
void populateEnvironReadOnlyTable ()
 Populate the readonly environment variable table with names and values by examining all the full_uri columns. More...
 
bool convertLibrary (const wxString &aLibrary, const wxString &legacyFilepath, const wxString &newFilepath)
 
SYMBOL_LIB_TABLE_GRIDglobal_model () const
 
SYMBOL_LIB_TABLE_GRIDproject_model () const
 
SYMBOL_LIB_TABLE_GRIDcur_model () const
 

Private Attributes

SYMBOL_LIB_TABLEm_globalTable
 
SYMBOL_LIB_TABLEm_projectTable
 
PROJECTm_project
 
DIALOG_EDIT_LIBRARY_TABLESm_parent
 
WX_GRIDm_cur_grid
 changed based on tab choice More...
 
wxString m_lastProjectLibDir
 

Static Private Attributes

static size_t m_pageNdx = 0
 Remember the last notebook page selected. More...
 

Detailed Description

Dialog to show and edit symbol library tables.

Definition at line 35 of file panel_sym_lib_table.h.

Constructor & Destructor Documentation

◆ PANEL_SYM_LIB_TABLE()

PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE ( DIALOG_EDIT_LIBRARY_TABLES aParent,
PROJECT m_project,
SYMBOL_LIB_TABLE aGlobal,
const wxString &  aGlobalTablePath,
SYMBOL_LIB_TABLE aProject,
const wxString &  aProjectTablePath 
)

Definition at line 198 of file panel_sym_lib_table.cpp.

202 :
203 PANEL_SYM_LIB_TABLE_BASE( aParent ),
204 m_globalTable( aGlobalTable ),
205 m_projectTable( aProjectTable ),
206 m_project( aProject ),
207 m_parent( aParent )
208{
209 // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
210 // so make it a grid owned table.
212
213 wxArrayString pluginChoices;
214
215 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) );
216 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
217 pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_DATABASE ) );
218
219 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
220
221 if( cfg->m_lastSymbolLibDir.IsEmpty() )
223
225
226 auto setupGrid =
227 [&]( WX_GRID* aGrid )
228 {
229 // Give a bit more room for combobox editors
230 aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
231
232 // add Cut, Copy, and Paste to wxGrids
233 aGrid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, aGrid ) );
234
235 aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
236 aGrid->AutoSizeColumns( false );
237
238 // Set special attributes
239 wxGridCellAttr* attr;
240
241 attr = new wxGridCellAttr;
242
243 wxString wildcards = AllSymbolLibFilesWildcard()
246 attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, aGrid,
247 &cfg->m_lastSymbolLibDir, wildcards,
248 true, m_project->GetProjectPath() ) );
249 aGrid->SetColAttr( COL_URI, attr );
250
251 attr = new wxGridCellAttr;
252 attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) );
253 aGrid->SetColAttr( COL_TYPE, attr );
254
255 attr = new wxGridCellAttr;
256 attr->SetRenderer( new wxGridCellBoolRenderer() );
257 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
258 aGrid->SetColAttr( COL_ENABLED, attr );
259
260 attr = new wxGridCellAttr;
261 attr->SetRenderer( new wxGridCellBoolRenderer() );
262 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
263 aGrid->SetColAttr( COL_VISIBLE, attr );
264
265 // all but COL_OPTIONS, which is edited with Option Editor anyways.
266 aGrid->AutoSizeColumn( COL_NICKNAME, false );
267 aGrid->AutoSizeColumn( COL_TYPE, false );
268 aGrid->AutoSizeColumn( COL_URI, false );
269 aGrid->AutoSizeColumn( COL_DESCR, false );
270 aGrid->AutoSizeColumn( COL_ENABLED, false );
271
272 // would set this to width of title, if it was easily known.
273 aGrid->SetColSize( COL_OPTIONS, 80 );
274
275 // Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
276 // a currentCell which is sometimes not highlighted.
277 if( aGrid->GetNumberRows() > 0 )
278 aGrid->SelectRow( 0 );
279 };
280
281 setupGrid( m_global_grid );
282
283 if( m_projectTable )
284 {
286 setupGrid( m_project_grid );
287 }
288 else
289 {
290 m_pageNdx = 0;
291 m_notebook->DeletePage( 1 );
292 m_project_grid = nullptr;
293 }
294
295 // add Cut, Copy, and Paste to wxGrids
296 m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
297
299
300 // select the last selected page
301 m_notebook->SetSelection( m_pageNdx );
303
304 m_path_subs_grid->SetColLabelValue( 0, _( "Name" ) );
305 m_path_subs_grid->SetColLabelValue( 1, _( "Value" ) );
306
307 // for ALT+A handling, we want the initial focus to be on the first selected grid.
309
310 // Configure button logos
316}
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
@ small_folder
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
PANEL_SYM_LIB_TABLE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
SYMBOL_LIB_TABLE * m_projectTable
static size_t m_pageNdx
Remember the last notebook page selected.
SYMBOL_LIB_TABLE * m_globalTable
void populateEnvironReadOnlyTable()
Populate the readonly environment variable table with names and values by examining all the full_uri ...
WX_GRID * m_cur_grid
changed based on tab choice
DIALOG_EDIT_LIBRARY_TABLES * m_parent
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:97
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:125
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
Definition: sch_io_mgr.cpp:81
Build a wxGridTableBase by wrapping an SYMBOL_LIB_TABLE object.
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:93
#define _(s)
wxString LegacySymbolLibFileWildcard()
wxString KiCadSymbolLibFileWildcard()
wxString AllSymbolLibFilesWildcard()
@ COL_DESCR
@ COL_NICKNAME
@ COL_OPTIONS
@ COL_ENABLED
@ COL_URI
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111

References _, AllSymbolLibFilesWildcard(), COL_DESCR, COL_ENABLED, COL_NICKNAME, COL_OPTIONS, COL_TYPE, COL_URI, COL_VISIBLE, PATHS::GetDefaultUserSymbolsPath(), PROJECT::GetProjectPath(), KiBitmap(), KiCadSymbolLibFileWildcard(), LegacySymbolLibFileWildcard(), PANEL_SYM_LIB_TABLE_BASE::m_append_button, PANEL_SYM_LIB_TABLE_BASE::m_browse_button, m_cur_grid, PANEL_SYM_LIB_TABLE_BASE::m_delete_button, PANEL_SYM_LIB_TABLE_BASE::m_global_grid, m_globalTable, m_lastProjectLibDir, EESCHEMA_SETTINGS::m_lastSymbolLibDir, PANEL_SYM_LIB_TABLE_BASE::m_move_down_button, PANEL_SYM_LIB_TABLE_BASE::m_move_up_button, PANEL_SYM_LIB_TABLE_BASE::m_notebook, m_pageNdx, m_parent, PANEL_SYM_LIB_TABLE_BASE::m_path_subs_grid, m_project, PANEL_SYM_LIB_TABLE_BASE::m_project_grid, m_projectTable, Pgm(), populateEnvironReadOnlyTable(), DIALOG_SHIM::SetInitialFocus(), WX_GRID::SetTable(), SCH_IO_MGR::ShowType(), small_down, small_folder, small_plus, small_trash, and small_up.

◆ ~PANEL_SYM_LIB_TABLE()

PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE ( )
virtual

Definition at line 319 of file panel_sym_lib_table.cpp.

320{
321 // Delete the GRID_TRICKS.
322 // Any additional event handlers should be popped before the window is deleted.
323 m_global_grid->PopEventHandler( true );
324
325 if( m_project_grid )
326 m_project_grid->PopEventHandler( true );
327
328 m_path_subs_grid->PopEventHandler( true );
329}

References PANEL_SYM_LIB_TABLE_BASE::m_global_grid, PANEL_SYM_LIB_TABLE_BASE::m_path_subs_grid, and PANEL_SYM_LIB_TABLE_BASE::m_project_grid.

Member Function Documentation

◆ adjustPathSubsGridColumns()

void PANEL_SYM_LIB_TABLE::adjustPathSubsGridColumns ( int  aWidth)
private

Definition at line 969 of file panel_sym_lib_table.cpp.

970{
971 // Account for scroll bars
972 aWidth -= ( m_path_subs_grid->GetSize().x - m_path_subs_grid->GetClientSize().x );
973
974 m_path_subs_grid->AutoSizeColumn( 0 );
975
976 int remaining_width = aWidth - m_path_subs_grid->GetColSize( 0 );
977
978 if( remaining_width < 0 )
979 m_path_subs_grid->SetColSize( 1, -1 );
980 else
981 m_path_subs_grid->SetColSize( 1, remaining_width );
982}

References PANEL_SYM_LIB_TABLE_BASE::m_path_subs_grid.

Referenced by onSizeGrid(), and populateEnvironReadOnlyTable().

◆ appendRowHandler()

void PANEL_SYM_LIB_TABLE::appendRowHandler ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 575 of file panel_sym_lib_table.cpp.

576{
578 return;
579
580 if( m_cur_grid->AppendRows( 1 ) )
581 {
582 int row = m_cur_grid->GetNumberRows() - 1;
583
584 // wx documentation is wrong, SetGridCursor does not make visible.
585 m_cur_grid->MakeCellVisible( row, 0 );
586 m_cur_grid->SetGridCursor( row, 1 );
587 m_cur_grid->EnableCellEditControl( true );
588 m_cur_grid->ShowCellEditControl();
589 }
590}
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:226

References WX_GRID::CommitPendingChanges(), and m_cur_grid.

◆ browseLibrariesHandler()

void PANEL_SYM_LIB_TABLE::browseLibrariesHandler ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 484 of file panel_sym_lib_table.cpp.

485{
486 wxString wildcards = AllSymbolLibFilesWildcard()
489 + "|" + DatabaseLibFileWildcard();
490
491 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
492
493 wxString openDir = cfg->m_lastSymbolLibDir;
494
496 openDir = m_lastProjectLibDir;
497
498 wxFileDialog dlg( this, _( "Select Library" ), openDir, wxEmptyString, wildcards,
499 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
500
501 if( dlg.ShowModal() == wxID_CANCEL )
502 return;
503
505 cfg->m_lastSymbolLibDir = dlg.GetDirectory();
506 else
507 m_lastProjectLibDir = dlg.GetDirectory();
508
509 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
510 bool addDuplicates = false;
511 bool applyToAll = false;
512 wxString warning = _( "Warning: Duplicate Nickname" );
513 wxString msg = _( "A library nicknamed '%s' already exists." );
514 wxString detailedMsg = _( "One of the nicknames will need to be changed after "
515 "adding this library." );
516
517 wxArrayString filePathsList;
518 dlg.GetPaths( filePathsList );
519
520 for( const wxString& filePath : filePathsList )
521 {
522 wxFileName fn( filePath );
523 wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), true );
524 bool doAdd = true;
525
526 if( cur_model()->ContainsNickname( nickname ) )
527 {
528 if( !applyToAll )
529 {
530 // The cancel button adds the library to the table anyway
531 addDuplicates = OKOrCancelDialog( this, warning, wxString::Format( msg, nickname ),
532 detailedMsg, _( "Skip" ), _( "Add Anyway" ),
533 &applyToAll ) == wxID_CANCEL;
534 }
535
536 doAdd = addDuplicates;
537 }
538
539 if( doAdd && m_cur_grid->AppendRows( 1 ) )
540 {
541 int last_row = m_cur_grid->GetNumberRows() - 1;
542
543 m_cur_grid->SetCellValue( last_row, COL_NICKNAME, nickname );
544
545 // attempt to auto-detect the plugin type
546 for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
547 {
548 if( SCH_IO_MGR::GetLibraryFileExtension( piType ).Lower() == fn.GetExt().Lower() )
549 {
550 m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( piType ) );
551 break;
552 }
553 }
554
555 // try to use path normalized to an environmental variable or project path
556 wxString path = NormalizePath( filePath, &envVars, m_project->GetProjectPath() );
557
558 // Do not use the project path in the global library table. This will almost
559 // assuredly be wrong for a different project.
560 if( m_pageNdx == 0 && path.Contains( "${KIPRJMOD}" ) )
561 path = fn.GetFullPath();
562
563 m_cur_grid->SetCellValue( last_row, COL_URI, path );
564 }
565 }
566
567 if( !filePathsList.IsEmpty() )
568 {
569 m_cur_grid->MakeCellVisible( m_cur_grid->GetNumberRows() - 1, 0 );
570 m_cur_grid->SetGridCursor( m_cur_grid->GetNumberRows() - 1, 1 );
571 }
572}
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:190
SYMBOL_LIB_TABLE_GRID * cur_model() const
static const wxString GetLibraryFileExtension(SCH_FILE_T aFileType)
Return the symbol library file extension (if any) for aFileType.
Definition: sch_io_mgr.cpp:141
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:253
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Definition: env_paths.cpp:71
wxString DatabaseLibFileWildcard()
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

References _, AllSymbolLibFilesWildcard(), COL_NICKNAME, COL_TYPE, COL_URI, cur_model(), DatabaseLibFileWildcard(), LIB_ID::FixIllegalChars(), Format(), SCH_IO_MGR::GetLibraryFileExtension(), PROJECT::GetProjectPath(), KiCadSymbolLibFileWildcard(), LegacySymbolLibFileWildcard(), m_cur_grid, PANEL_SYM_LIB_TABLE_BASE::m_global_grid, m_lastProjectLibDir, EESCHEMA_SETTINGS::m_lastSymbolLibDir, m_pageNdx, m_project, PANEL_SYM_LIB_TABLE_BASE::m_project_grid, NormalizePath(), OKOrCancelDialog(), path, Pgm(), and SCH_IO_MGR::ShowType().

◆ convertLibrary()

bool PANEL_SYM_LIB_TABLE::convertLibrary ( const wxString &  aLibrary,
const wxString &  legacyFilepath,
const wxString &  newFilepath 
)
private

Definition at line 812 of file panel_sym_lib_table.cpp.

814{
815 SCH_PLUGIN::SCH_PLUGIN_RELEASER legacyPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
816 SCH_PLUGIN::SCH_PLUGIN_RELEASER kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
817 std::vector<LIB_SYMBOL*> symbols;
818 std::vector<LIB_SYMBOL*> newSymbols;
819 std::map<LIB_SYMBOL*, LIB_SYMBOL*> symbolMap;
820
821 try
822 {
823 // Write a stub file; SaveSymbol() expects something to be there already.
824 FILE_OUTPUTFORMATTER* formatter = new FILE_OUTPUTFORMATTER( newFilepath );
825
826 formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator kicad_converter))",
828
829 // This will write the file
830 delete formatter;
831
832 legacyPI->EnumerateSymbolLib( symbols, legacyFilepath );
833
834 // Copy non-aliases first so we can build a map from symbols to newSymbols
835 for( LIB_SYMBOL* symbol : symbols )
836 {
837 if( symbol->IsAlias() )
838 continue;
839
840 symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
841
842 newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
843 symbolMap[symbol] = newSymbols.back();
844 }
845
846 // Now do the aliases using the map to hook them up to their newSymbol parents
847 for( LIB_SYMBOL* symbol : symbols )
848 {
849 if( !symbol->IsAlias() )
850 continue;
851
852 symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
853
854 newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
855 newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] );
856 }
857
858 // Finally write out newSymbols
859 for( LIB_SYMBOL* symbol : newSymbols )
860 {
861 kicadPI->SaveSymbol( newFilepath, symbol );
862 }
863 }
864 catch( ... )
865 {
866 return false;
867 }
868
869 return true;
870}
Used for text file output.
Definition: richio.h:457
Define a library symbol object.
Definition: lib_symbol.h:98
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:431
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:535
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
Definition: string_utils.h:55

References CTX_LIBID, SCH_PLUGIN::EnumerateSymbolLib(), EscapeString(), OUTPUTFORMATTER::Print(), SCH_PLUGIN::SaveSymbol(), and SEXPR_SYMBOL_LIB_FILE_VERSION.

Referenced by onConvertLegacyLibraries().

◆ cur_model()

SYMBOL_LIB_TABLE_GRID * PANEL_SYM_LIB_TABLE::cur_model ( ) const
private

Definition at line 1005 of file panel_sym_lib_table.cpp.

1006{
1007 return (SYMBOL_LIB_TABLE_GRID*) m_cur_grid->GetTable();
1008}

References m_cur_grid.

Referenced by browseLibrariesHandler(), moveDownHandler(), moveUpHandler(), and verifyTables().

◆ deleteRowHandler()

void PANEL_SYM_LIB_TABLE::deleteRowHandler ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 593 of file panel_sym_lib_table.cpp.

594{
596 return;
597
598 int curRow = m_cur_grid->GetGridCursorRow();
599 int curCol = m_cur_grid->GetGridCursorCol();
600
601 // In a wxGrid, collect rows that have a selected cell, or are selected
602 // It is not so easy: it depends on the way the selection was made.
603 // Here, we collect rows selected by clicking on a row label, and rows that contain
604 // previously-selected cells.
605 // If no candidate, just delete the row with the grid cursor.
606 wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
607 wxGridCellCoordsArray cells = m_cur_grid->GetSelectedCells();
608 wxGridCellCoordsArray blockTopLeft = m_cur_grid->GetSelectionBlockTopLeft();
609 wxGridCellCoordsArray blockBotRight = m_cur_grid->GetSelectionBlockBottomRight();
610
611 // Add all row having cell selected to list:
612 for( unsigned ii = 0; ii < cells.GetCount(); ii++ )
613 selectedRows.Add( cells[ii].GetRow() );
614
615 // Handle block selection
616 if( !blockTopLeft.IsEmpty() && !blockBotRight.IsEmpty() )
617 {
618 for( int i = blockTopLeft[0].GetRow(); i <= blockBotRight[0].GetRow(); ++i )
619 selectedRows.Add( i );
620 }
621
622 // Use the row having the grid cursor only if we have no candidate:
623 if( selectedRows.size() == 0 && m_cur_grid->GetGridCursorRow() >= 0 )
624 selectedRows.Add( m_cur_grid->GetGridCursorRow() );
625
626 if( selectedRows.size() == 0 )
627 {
628 wxBell();
629 return;
630 }
631
632 std::sort( selectedRows.begin(), selectedRows.end() );
633
634 // Remove selected rows (note: a row can be stored more than once in list)
635 int last_row = -1;
636
637 for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
638 {
639 int row = selectedRows[ii];
640
641 if( row != last_row )
642 {
643 last_row = row;
644 m_cur_grid->DeleteRows( row, 1 );
645 }
646 }
647
648 if( m_cur_grid->GetNumberRows() > 0 && curRow >= 0 )
649 m_cur_grid->SetGridCursor( std::min( curRow, m_cur_grid->GetNumberRows() - 1 ), curCol );
650}

References WX_GRID::CommitPendingChanges(), and m_cur_grid.

◆ global_model()

SYMBOL_LIB_TABLE_GRID * PANEL_SYM_LIB_TABLE::global_model ( ) const
private

◆ moveDownHandler()

void PANEL_SYM_LIB_TABLE::moveDownHandler ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 683 of file panel_sym_lib_table.cpp.

684{
686 return;
687
689 int curRow = m_cur_grid->GetGridCursorRow();
690
691 // @todo: add multiple selection moves.
692 if( unsigned( curRow + 1 ) < tbl->rows.size() )
693 {
694 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
695 tbl->rows.release( tbl->rows.begin() + curRow );
696
697 ++curRow;
698 tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
699
700 if( tbl->GetView() )
701 {
702 // Update the wxGrid
703 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow - 1, 0 );
704 tbl->GetView()->ProcessTableMessage( msg );
705 }
706
707 m_cur_grid->MakeCellVisible( curRow, m_cur_grid->GetGridCursorCol() );
708 m_cur_grid->SetGridCursor( curRow, m_cur_grid->GetGridCursorCol() );
709 }
710}
LIB_TABLE_ROWS rows

References WX_GRID::CommitPendingChanges(), cur_model(), m_cur_grid, and LIB_TABLE::rows.

◆ moveUpHandler()

void PANEL_SYM_LIB_TABLE::moveUpHandler ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 653 of file panel_sym_lib_table.cpp.

654{
656 return;
657
659 int curRow = m_cur_grid->GetGridCursorRow();
660
661 // @todo: add multiple selection moves.
662 if( curRow >= 1 )
663 {
664 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
665 tbl->rows.release( tbl->rows.begin() + curRow );
666
667 --curRow;
668 tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
669
670 if( tbl->GetView() )
671 {
672 // Update the wxGrid
673 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow, 0 );
674 tbl->GetView()->ProcessTableMessage( msg );
675 }
676
677 m_cur_grid->MakeCellVisible( curRow, m_cur_grid->GetGridCursorCol() );
678 m_cur_grid->SetGridCursor( curRow, m_cur_grid->GetGridCursorCol() );
679 }
680}

References WX_GRID::CommitPendingChanges(), cur_model(), m_cur_grid, and LIB_TABLE::rows.

◆ onConvertLegacyLibraries()

void PANEL_SYM_LIB_TABLE::onConvertLegacyLibraries ( wxCommandEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 713 of file panel_sym_lib_table.cpp.

714{
716 return;
717
718 wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
719
720 if( selectedRows.empty() && m_cur_grid->GetGridCursorRow() >= 0 )
721 selectedRows.push_back( m_cur_grid->GetGridCursorRow() );
722
723 wxArrayInt legacyRows;
724 wxString legacyType = SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY );
725 wxString kicadType = SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD );
726 wxString msg;
727
728 for( int row : selectedRows )
729 {
730 if( m_cur_grid->GetCellValue( row, COL_TYPE ) == legacyType )
731 legacyRows.push_back( row );
732 }
733
734 if( legacyRows.size() <= 0 )
735 {
736 wxMessageBox( _( "Select one or more rows containing libraries in Legacy format (*.lib) "
737 "to save as current KiCad format (*.kicad_sym)." ) );
738 return;
739 }
740 else
741 {
742 if( legacyRows.size() == 1 )
743 {
744 msg.Printf( _( "Save '%s' as current KiCad format (*.kicad_sym) "
745 "and replace legacy entry in table?" ),
746 m_cur_grid->GetCellValue( legacyRows[0], COL_NICKNAME ) );
747 }
748 else
749 {
750 msg.Printf( _( "Save %d Legacy format libraries as current KiCad format (*.kicad_sym) "
751 "and replace legacy entries in table?" ),
752 (int) legacyRows.size() );
753 }
754
755 if( !IsOK( m_parent, msg ) )
756 return;
757 }
758
759 for( int row : legacyRows )
760 {
761 wxString libName = m_cur_grid->GetCellValue( row, COL_NICKNAME );
762 wxString relPath = m_cur_grid->GetCellValue( row, COL_URI );
763 wxString resolvedPath = ExpandEnvVarSubstitutions( relPath, m_project );
764 wxFileName legacyLib( resolvedPath );
765
766 if( !legacyLib.Exists() )
767 {
768 msg.Printf( _( "Library '%s' not found." ), relPath );
769 DisplayErrorMessage( this, msg );
770 continue;
771 }
772
773 wxFileName newLib( resolvedPath );
774 newLib.SetExt( "kicad_sym" );
775
776 if( newLib.Exists() )
777 {
778 msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
779 newLib.GetFullPath() );
780
781 switch( wxMessageBox( msg, _( "Migrate Library" ),
782 wxYES_NO | wxCANCEL | wxICON_QUESTION, m_parent ) )
783 {
784 case wxYES: break;
785 case wxNO: continue;
786 case wxCANCEL: return;
787 }
788 }
789
790 if( convertLibrary( libName, legacyLib.GetFullPath(), newLib.GetFullPath() ) )
791 {
792 relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(),
793 m_project );
794
795 // Do not use the project path in the global library table. This will almost
796 // assuredly be wrong for a different project.
797 if( m_cur_grid == m_global_grid && relPath.Contains( "${KIPRJMOD}" ) )
798 relPath = newLib.GetFullPath();
799
800 m_cur_grid->SetCellValue( row, COL_URI, relPath );
801 m_cur_grid->SetCellValue( row, COL_TYPE, kicadType );
802 }
803 else
804 {
805 msg.Printf( _( "Failed to save symbol library file '%s'." ), newLib.GetFullPath() );
806 DisplayErrorMessage( this, msg );
807 }
808 }
809}
bool convertLibrary(const wxString &aLibrary, const wxString &legacyFilepath, const wxString &newFilepath)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:267
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:342
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299

References _, COL_NICKNAME, COL_TYPE, COL_URI, WX_GRID::CommitPendingChanges(), convertLibrary(), DisplayErrorMessage(), ExpandEnvVarSubstitutions(), IsOK(), m_cur_grid, PANEL_SYM_LIB_TABLE_BASE::m_global_grid, m_parent, m_project, NormalizePath(), Pgm(), and SCH_IO_MGR::ShowType().

◆ onSizeGrid()

void PANEL_SYM_LIB_TABLE::onSizeGrid ( wxSizeEvent &  event)
overrideprivatevirtual

Reimplemented from PANEL_SYM_LIB_TABLE_BASE.

Definition at line 985 of file panel_sym_lib_table.cpp.

986{
987 adjustPathSubsGridColumns( event.GetSize().GetX() );
988
989 event.Skip();
990}
void adjustPathSubsGridColumns(int aWidth)

References adjustPathSubsGridColumns().

◆ OnUpdateUI()

void PANEL_SYM_LIB_TABLE::OnUpdateUI ( wxUpdateUIEvent &  event)
overrideprivatevirtual

◆ populateEnvironReadOnlyTable()

void PANEL_SYM_LIB_TABLE::populateEnvironReadOnlyTable ( )
private

Populate the readonly environment variable table with names and values by examining all the full_uri columns.

Definition at line 905 of file panel_sym_lib_table.cpp.

906{
907 wxRegEx re( ".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
908 wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
909
910 std::set< wxString > unique;
911
912 // clear the table
914
916 {
917 if( !tbl )
918 continue;
919
920 for( int row = 0; row < tbl->GetNumberRows(); ++row )
921 {
922 wxString uri = tbl->GetValue( row, COL_URI );
923
924 while( re.Matches( uri ) )
925 {
926 wxString envvar = re.GetMatch( uri, 2 );
927
928 // if not ${...} form then must be $(...)
929 if( envvar.IsEmpty() )
930 envvar = re.GetMatch( uri, 4 );
931
932 // ignore duplicates
933 unique.insert( envvar );
934
935 // delete the last match and search again
936 uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
937 }
938 }
939 }
940
941 // Make sure this special environment variable shows up even if it was
942 // not used yet. It is automatically set by KiCad to the directory holding
943 // the current project.
944 unique.insert( PROJECT_VAR_NAME );
946
947 for( const wxString& evName : unique )
948 {
949 int row = m_path_subs_grid->GetNumberRows();
950 m_path_subs_grid->AppendRows( 1 );
951
952 m_path_subs_grid->SetCellValue( row, 0, wxT( "${" ) + evName + wxT( "}" ) );
953 m_path_subs_grid->SetCellEditor( row, 0, new GRID_CELL_READONLY_TEXT_EDITOR() );
954
955 wxString evValue;
956 wxGetEnv( evName, &evValue );
957 m_path_subs_grid->SetCellValue( row, 1, evValue );
958 m_path_subs_grid->SetCellEditor( row, 1, new GRID_CELL_READONLY_TEXT_EDITOR() );
959 }
960
961 // No combobox editors here, but it looks better if its consistent with the other
962 // grids in the dialog.
963 m_path_subs_grid->SetDefaultRowSize( m_path_subs_grid->GetDefaultRowSize() + 2 );
964
965 adjustPathSubsGridColumns( m_path_subs_grid->GetRect().GetWidth() );
966}
SYMBOL_LIB_TABLE_GRID * global_model() const
SYMBOL_LIB_TABLE_GRID * project_model() const
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:109
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:38

References adjustPathSubsGridColumns(), WX_GRID::ClearRows(), COL_URI, global_model(), SYMBOL_LIB_TABLE::GlobalPathEnvVariableName(), PANEL_SYM_LIB_TABLE_BASE::m_path_subs_grid, project_model(), and PROJECT_VAR_NAME.

Referenced by PANEL_SYM_LIB_TABLE().

◆ project_model()

SYMBOL_LIB_TABLE_GRID * PANEL_SYM_LIB_TABLE::project_model ( ) const
private

Definition at line 999 of file panel_sym_lib_table.cpp.

1000{
1001 return m_project_grid ? (SYMBOL_LIB_TABLE_GRID*) m_project_grid->GetTable() : nullptr;
1002}

References PANEL_SYM_LIB_TABLE_BASE::m_project_grid.

Referenced by populateEnvironReadOnlyTable(), TransferDataFromWindow(), and verifyTables().

◆ TransferDataFromWindow()

bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow ( )
overrideprivate

Definition at line 873 of file panel_sym_lib_table.cpp.

874{
876 return false;
877
878 if( !verifyTables() )
879 return false;
880
881 if( *global_model() != *m_globalTable )
882 {
884
886 m_globalTable->rows.transfer( m_globalTable->rows.end(), global_model()->rows.begin(),
887 global_model()->rows.end(), global_model()->rows );
889 }
890
892 {
894
896 m_projectTable->rows.transfer( m_projectTable->rows.end(), project_model()->rows.begin(),
897 project_model()->rows.end(), project_model()->rows );
899 }
900
901 return true;
902}
void Clear()
Delete all rows.
void reindex()
bool verifyTables()
Trim important fields, removes blank row entries, and checks for duplicates.
LIB_TABLE_ROWS_ITER begin() override

References SYMBOL_LIB_TABLE_GRID::begin(), LIB_TABLE::Clear(), WX_GRID::CommitPendingChanges(), global_model(), m_cur_grid, m_globalTable, DIALOG_EDIT_LIBRARY_TABLES::m_GlobalTableChanged, m_parent, m_projectTable, DIALOG_EDIT_LIBRARY_TABLES::m_ProjectTableChanged, project_model(), LIB_TABLE::reindex(), LIB_TABLE::rows, and verifyTables().

◆ verifyTables()

bool PANEL_SYM_LIB_TABLE::verifyTables ( )
private

Trim important fields, removes blank row entries, and checks for duplicates.

Returns
bool - true if tables are OK, else false.

Definition at line 332 of file panel_sym_lib_table.cpp.

333{
334 wxString msg;
335
336 for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
337 {
338 if( !model )
339 continue;
340
341 for( int r = 0; r < model->GetNumberRows(); )
342 {
343 wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
344 wxString uri = model->GetValue( r, COL_URI ).Trim( false ).Trim();
345 unsigned illegalCh = 0;
346
347 if( !nick || !uri )
348 {
349 if( !nick && !uri )
350 msg = _( "A library table row nickname and path cells are empty." );
351 else if( !nick )
352 msg = _( "A library table row nickname cell is empty." );
353 else
354 msg = _( "A library table row path cell is empty." );
355
356 wxMessageDialog badCellDlg( this, msg, _( "Invalid Row Definition" ),
357 wxYES_NO | wxCENTER | wxICON_QUESTION | wxYES_DEFAULT );
358 badCellDlg.SetExtendedMessage( _( "Empty cells will result in all rows that are "
359 "invalid to be removed from the table." ) );
360 badCellDlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Remove Invalid Cells" ) ),
361 wxMessageDialog::ButtonLabel( _( "Cancel Table Update" ) ) );
362
363 if( badCellDlg.ShowModal() == wxID_NO )
364 return false;
365
366 // Delete the "empty" row, where empty means missing nick or uri.
367 // This also updates the UI which could be slow, but there should only be a few
368 // rows to delete, unless the user fell asleep on the Add Row
369 // button.
370 model->DeleteRows( r, 1 );
371 }
372 else if( ( illegalCh = LIB_ID::FindIllegalLibraryNameChar( nick ) ) )
373 {
374 msg = wxString::Format( _( "Illegal character '%c' in nickname '%s'" ),
375 illegalCh,
376 nick );
377
378 // show the tabbed panel holding the grid we have flunked:
379 if( model != cur_model() )
380 m_notebook->SetSelection( model == global_model() ? 0 : 1 );
381
382 m_cur_grid->MakeCellVisible( r, 0 );
383 m_cur_grid->SetGridCursor( r, 1 );
384
385 wxMessageDialog errdlg( this, msg, _( "Library Nickname Error" ) );
386 errdlg.ShowModal();
387 return false;
388 }
389 else
390 {
391 // set the trimmed values back into the table so they get saved to disk.
392 model->SetValue( r, COL_NICKNAME, nick );
393 model->SetValue( r, COL_URI, uri );
394 ++r; // this row was OK.
395 }
396 }
397 }
398
399 // check for duplicate nickNames, separately in each table.
400 for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
401 {
402 if( !model )
403 continue;
404
405 for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
406 {
407 wxString nick1 = model->GetValue( r1, COL_NICKNAME );
408
409 for( int r2=r1+1; r2 < model->GetNumberRows(); ++r2 )
410 {
411 wxString nick2 = model->GetValue( r2, COL_NICKNAME );
412
413 if( nick1 == nick2 )
414 {
415 msg = wxString::Format( _( "Multiple libraries cannot share the same "
416 "nickname ('%s')." ), nick1 );
417
418 // show the tabbed panel holding the grid we have flunked:
419 if( model != cur_model() )
420 m_notebook->SetSelection( model == global_model() ? 0 : 1 );
421
422 // go to the lower of the two rows, it is technically the duplicate:
423 m_cur_grid->MakeCellVisible( r2, 0 );
424 m_cur_grid->SetGridCursor( r2, 1 );
425
426 wxMessageDialog errdlg( this, msg, _( "Library Nickname Error" ) );
427 errdlg.ShowModal();
428
429 return false;
430 }
431 }
432 }
433 }
434
435 for( SYMBOL_LIB_TABLE* table : { global_model(), project_model() } )
436 {
437 if( !table )
438 continue;
439
440 for( unsigned int r = 0; r < table->GetCount(); ++r )
441 {
442 SYMBOL_LIB_TABLE_ROW& row = dynamic_cast<SYMBOL_LIB_TABLE_ROW&>( table->At( r ) );
443
444 if( !row.GetParent() )
445 row.SetParent( table );
446
447 if( !row.GetIsEnabled() )
448 continue;
449
450 try
451 {
452 if( row.Refresh() )
453 {
454 if( table == global_model() )
456 else
458 }
459 }
460 catch( const IO_ERROR& ioe )
461 {
462 msg.Printf( _( "Symbol library '%s' failed to load." ), row.GetNickName() );
463
464 wxMessageDialog errdlg( this, msg + wxS( "\n" ) + ioe.What(),
465 _( "Error Loading Library" ) );
466 errdlg.ShowModal();
467
468 return true;
469 }
470 }
471 }
472
473 return true;
474}
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
static unsigned FindIllegalLibraryNameChar(const UTF8 &aLibraryName)
Looks for characters that are illegal in library nicknames.
Definition: lib_id.cpp:242
LIB_TABLE * GetParent() const
void SetParent(LIB_TABLE *aParent)
const wxString & GetNickName() const
bool GetIsEnabled() const
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
bool Refresh()
Attempt to reload the library.
E_SERIE r
Definition: eserie.cpp:41

References _, COL_NICKNAME, COL_URI, cur_model(), LIB_ID::FindIllegalLibraryNameChar(), Format(), LIB_TABLE_ROW::GetIsEnabled(), LIB_TABLE_ROW::GetNickName(), LIB_TABLE_ROW::GetParent(), global_model(), m_cur_grid, DIALOG_EDIT_LIBRARY_TABLES::m_GlobalTableChanged, PANEL_SYM_LIB_TABLE_BASE::m_notebook, m_parent, DIALOG_EDIT_LIBRARY_TABLES::m_ProjectTableChanged, project_model(), r, SYMBOL_LIB_TABLE_ROW::Refresh(), LIB_TABLE_ROW::SetParent(), and IO_ERROR::What().

Referenced by TransferDataFromWindow().

Member Data Documentation

◆ m_append_button

wxBitmapButton* PANEL_SYM_LIB_TABLE_BASE::m_append_button
protectedinherited

◆ m_browse_button

wxBitmapButton* PANEL_SYM_LIB_TABLE_BASE::m_browse_button
protectedinherited

◆ m_convertLegacy

wxButton* PANEL_SYM_LIB_TABLE_BASE::m_convertLegacy
protectedinherited

◆ m_cur_grid

◆ m_delete_button

wxBitmapButton* PANEL_SYM_LIB_TABLE_BASE::m_delete_button
protectedinherited

◆ m_global_grid

◆ m_global_panel

wxPanel* PANEL_SYM_LIB_TABLE_BASE::m_global_panel
protectedinherited

◆ m_globalTable

SYMBOL_LIB_TABLE* PANEL_SYM_LIB_TABLE::m_globalTable
private

Definition at line 79 of file panel_sym_lib_table.h.

Referenced by PANEL_SYM_LIB_TABLE(), and TransferDataFromWindow().

◆ m_lastProjectLibDir

wxString PANEL_SYM_LIB_TABLE::m_lastProjectLibDir
private

Definition at line 87 of file panel_sym_lib_table.h.

Referenced by browseLibrariesHandler(), and PANEL_SYM_LIB_TABLE().

◆ m_move_down_button

wxBitmapButton* PANEL_SYM_LIB_TABLE_BASE::m_move_down_button
protectedinherited

◆ m_move_up_button

wxBitmapButton* PANEL_SYM_LIB_TABLE_BASE::m_move_up_button
protectedinherited

◆ m_notebook

wxNotebook* PANEL_SYM_LIB_TABLE_BASE::m_notebook
protectedinherited

◆ m_pageNdx

size_t PANEL_SYM_LIB_TABLE::m_pageNdx = 0
staticprivate

Remember the last notebook page selected.

Definition at line 86 of file panel_sym_lib_table.h.

Referenced by browseLibrariesHandler(), OnUpdateUI(), and PANEL_SYM_LIB_TABLE().

◆ m_parent

DIALOG_EDIT_LIBRARY_TABLES* PANEL_SYM_LIB_TABLE::m_parent
private

◆ m_path_subs_grid

◆ m_project

PROJECT* PANEL_SYM_LIB_TABLE::m_project
private

◆ m_project_grid

WX_GRID* PANEL_SYM_LIB_TABLE_BASE::m_project_grid
protectedinherited

◆ m_project_panel

wxPanel* PANEL_SYM_LIB_TABLE_BASE::m_project_panel
protectedinherited

◆ m_projectTable

SYMBOL_LIB_TABLE* PANEL_SYM_LIB_TABLE::m_projectTable
private

Definition at line 80 of file panel_sym_lib_table.h.

Referenced by PANEL_SYM_LIB_TABLE(), and TransferDataFromWindow().


The documentation for this class was generated from the following files: