30#include <lib_table_lexer.h>
50#include <wx/filedlg.h>
99 return m_rows.insert( aIterator, aRow );
106 return m_rows.erase( aFirst, aLast );
110 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
117 wxFileName fn( aValue );
119 for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
154 size_t ndx = cb_text.find(
"(sym_lib_table" );
156 if( ndx != std::string::npos )
162 LIB_TABLE_LEXER lexer( &slr );
168 tmp_tbl.
Parse( &lexer );
182 for(
unsigned i = 0; i < tmp_tbl.
GetCount(); ++i )
186 m_grid->AutoSizeColumns(
false );
193 m_grid->AutoSizeColumns(
false );
201 const wxString& aGlobalTablePath,
203 const wxString& aProjectTablePath ) :
205 m_globalTable( aGlobalTable ),
206 m_projectTable( aProjectTable ),
207 m_project( aProject ),
214 wxArrayString pluginChoices;
228 [&](
WX_GRID* aGrid,
int aCol )
230 int prevWidth = aGrid->GetColSize( aCol );
232 aGrid->AutoSizeColumn( aCol,
false );
233 aGrid->SetColSize( aCol, std::max( prevWidth, aGrid->GetColSize( aCol ) ) );
240 aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
245 aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
248 wxGridCellAttr* attr;
250 attr =
new wxGridCellAttr;
258 aGrid->SetColAttr(
COL_URI, attr );
260 attr =
new wxGridCellAttr;
261 attr->SetEditor(
new wxGridCellChoiceEditor( pluginChoices ) );
262 aGrid->SetColAttr(
COL_TYPE, attr );
264 attr =
new wxGridCellAttr;
265 attr->SetRenderer(
new wxGridCellBoolRenderer() );
269 attr =
new wxGridCellAttr;
270 attr->SetRenderer(
new wxGridCellBoolRenderer() );
283 if( aGrid->GetNumberRows() > 0 )
284 aGrid->SelectRow( 0 );
347 for(
int r = 0; r < model->GetNumberRows(); )
349 wxString nick = model->GetValue( r,
COL_NICKNAME ).Trim(
false ).Trim();
350 wxString uri = model->GetValue( r,
COL_URI ).Trim(
false ).Trim();
351 unsigned illegalCh = 0;
356 msg =
_(
"A library table row nickname and path cells are empty." );
358 msg =
_(
"A library table row nickname cell is empty." );
360 msg =
_(
"A library table row path cell is empty." );
362 wxMessageDialog badCellDlg(
this, msg,
_(
"Invalid Row Definition" ),
363 wxYES_NO | wxCENTER | wxICON_QUESTION | wxYES_DEFAULT );
364 badCellDlg.SetExtendedMessage(
_(
"Empty cells will result in all rows that are "
365 "invalid to be removed from the table." ) );
366 badCellDlg.SetYesNoLabels( wxMessageDialog::ButtonLabel(
_(
"Remove Invalid Cells" ) ),
367 wxMessageDialog::ButtonLabel(
_(
"Cancel Table Update" ) ) );
369 if( badCellDlg.ShowModal() == wxID_NO )
376 model->DeleteRows( r, 1 );
391 wxMessageDialog errdlg(
this, msg,
_(
"Library Nickname Error" ) );
399 model->SetValue( r,
COL_URI, uri );
411 for(
int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
415 for(
int r2=r1+1; r2 < model->GetNumberRows(); ++r2 )
422 "nickname ('%s')." ), nick1 );
432 wxMessageDialog errdlg(
this, msg,
_(
"Library Nickname Error" ) );
446 for(
unsigned int r = 0; r < table->GetCount(); ++r )
468 msg.Printf(
_(
"Symbol library '%s' failed to load." ), row.
GetNickName() );
470 wxMessageDialog errdlg(
this, msg + wxS(
"\n" ) + ioe.
What(),
471 _(
"Error Loading Library" ) );
504 wxFileDialog dlg(
this,
_(
"Select Library" ), openDir, wxEmptyString, wildcards,
505 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
507 if( dlg.ShowModal() == wxID_CANCEL )
516 bool addDuplicates =
false;
517 bool applyToAll =
false;
518 wxString warning =
_(
"Warning: Duplicate Nickname" );
519 wxString msg =
_(
"A library nicknamed '%s' already exists." );
520 wxString detailedMsg =
_(
"One of the nicknames will need to be changed after "
521 "adding this library." );
523 wxArrayString filePathsList;
524 dlg.GetPaths( filePathsList );
526 for(
const wxString& filePath : filePathsList )
528 wxFileName fn( filePath );
532 if(
cur_model()->ContainsNickname( nickname ) )
538 detailedMsg,
_(
"Skip" ),
_(
"Add Anyway" ),
539 &applyToAll ) == wxID_CANCEL;
542 doAdd = addDuplicates;
547 int last_row =
m_cur_grid->GetNumberRows() - 1;
552 for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
567 path = fn.GetFullPath();
573 if( !filePathsList.IsEmpty() )
612 wxArrayInt selectedRows =
m_cur_grid->GetSelectedRows();
613 wxGridCellCoordsArray cells =
m_cur_grid->GetSelectedCells();
614 wxGridCellCoordsArray blockTopLeft =
m_cur_grid->GetSelectionBlockTopLeft();
615 wxGridCellCoordsArray blockBotRight =
m_cur_grid->GetSelectionBlockBottomRight();
618 for(
unsigned ii = 0; ii < cells.GetCount(); ii++ )
619 selectedRows.Add( cells[ii].GetRow() );
622 if( !blockTopLeft.IsEmpty() && !blockBotRight.IsEmpty() )
624 for(
int i = blockTopLeft[0].GetRow(); i <= blockBotRight[0].GetRow(); ++i )
625 selectedRows.Add( i );
629 if( selectedRows.size() == 0 &&
m_cur_grid->GetGridCursorRow() >= 0 )
630 selectedRows.Add(
m_cur_grid->GetGridCursorRow() );
632 if( selectedRows.size() == 0 )
638 std::sort( selectedRows.begin(), selectedRows.end() );
643 for(
int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
645 int row = selectedRows[ii];
647 if( row != last_row )
654 if(
m_cur_grid->GetNumberRows() > 0 && curRow >= 0 )
670 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
674 tbl->
m_rows.insert( tbl->
m_rows.begin() + curRow, move_me.release() );
679 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow, 0 );
680 tbl->GetView()->ProcessTableMessage( msg );
698 if(
unsigned( curRow + 1 ) < tbl->
m_rows.size() )
700 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
704 tbl->
m_rows.insert( tbl->
m_rows.begin() + curRow, move_me.release() );
709 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow - 1, 0 );
710 tbl->GetView()->ProcessTableMessage( msg );
724 wxArrayInt selectedRows =
m_cur_grid->GetSelectedRows();
726 if( selectedRows.empty() &&
m_cur_grid->GetGridCursorRow() >= 0 )
727 selectedRows.push_back(
m_cur_grid->GetGridCursorRow() );
729 wxArrayInt legacyRows;
734 for(
int row : selectedRows )
737 legacyRows.push_back( row );
740 if( legacyRows.size() <= 0 )
742 wxMessageBox(
_(
"Select one or more rows containing libraries in Legacy format (*.lib) "
743 "to save as current KiCad format (*.kicad_sym)." ) );
748 if( legacyRows.size() == 1 )
750 msg.Printf(
_(
"Save '%s' as current KiCad format (*.kicad_sym) "
751 "and replace legacy entry in table?" ),
756 msg.Printf(
_(
"Save %d Legacy format libraries as current KiCad format (*.kicad_sym) "
757 "and replace legacy entries in table?" ),
758 (
int) legacyRows.size() );
765 for(
int row : legacyRows )
770 wxFileName legacyLib( resolvedPath );
772 if( !legacyLib.Exists() )
774 msg.Printf(
_(
"Library '%s' not found." ), relPath );
779 wxFileName newLib( resolvedPath );
780 newLib.SetExt(
"kicad_sym" );
782 if( newLib.Exists() )
784 msg.Printf(
_(
"File '%s' already exists. Do you want overwrite this file?" ),
785 newLib.GetFullPath() );
787 switch( wxMessageBox( msg,
_(
"Migrate Library" ),
788 wxYES_NO | wxCANCEL | wxICON_QUESTION,
m_parent ) )
792 case wxCANCEL:
return;
796 if(
convertLibrary( libName, legacyLib.GetFullPath(), newLib.GetFullPath() ) )
798 relPath =
NormalizePath( newLib.GetFullPath(), &
Pgm().GetLocalEnvVariables(),
804 relPath = newLib.GetFullPath();
811 msg.Printf(
_(
"Failed to save symbol library file '%s'." ), newLib.GetFullPath() );
819 const wxString& newFilepath )
823 std::vector<LIB_SYMBOL*> symbols;
824 std::vector<LIB_SYMBOL*> newSymbols;
825 std::map<LIB_SYMBOL*, LIB_SYMBOL*> symbolMap;
832 formatter->
Print( 0,
"(kicad_symbol_lib (version %d) (generator kicad_converter))",
843 if( symbol->IsAlias() )
848 newSymbols.push_back(
new LIB_SYMBOL( *symbol ) );
849 symbolMap[symbol] = newSymbols.back();
855 if( !symbol->IsAlias() )
860 newSymbols.push_back(
new LIB_SYMBOL( *symbol ) );
861 newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] );
913 wxRegEx re(
".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
914 wxASSERT( re.IsValid() );
916 std::set< wxString > unique;
926 for(
int row = 0; row < tbl->GetNumberRows(); ++row )
928 wxString uri = tbl->GetValue( row,
COL_URI );
930 while( re.Matches( uri ) )
932 wxString envvar = re.GetMatch( uri, 2 );
935 if( envvar.IsEmpty() )
936 envvar = re.GetMatch( uri, 4 );
939 unique.insert( envvar );
942 uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
953 for(
const wxString& evName : unique )
958 m_path_subs_grid->SetCellValue( row, 0, wxT(
"${" ) + evName + wxT(
"}" ) );
962 wxGetEnv( evName, &evValue );
1027 wxString currentLib;
1031 projectTable = aKiway->
Prj().SchSymbolLibTable();
1035 currentLib = symbolEditor->GetCurLib();
1038 symbolEditor->FreezeLibraryTree();
1040 if( symbolEditor->HasLibModifications() )
1042 msg =
_(
"Modifications have been made to one or more symbol libraries.\n"
1043 "Changes must be saved or discarded before the symbol library "
1044 "table can be modified." );
1048 case wxID_YES: symbolEditor->SaveAll();
break;
1049 case wxID_NO: symbolEditor->RevertAll();
break;
1051 case wxID_CANCEL: symbolEditor->ThawLibraryTree();
return;
1060 projectTable, projectTableFn.GetFullPath() ) );
1062 if( dlg.ShowModal() == wxID_CANCEL )
1065 symbolEditor->ThawLibraryTree();
1074 globalTable->
Save( globalTablePath );
1078 msg.Printf(
_(
"Error saving global library table:\n\n%s" ), ioe.
What() );
1079 wxMessageBox( msg,
_(
"File Save Error" ), wxOK | wxICON_ERROR );
1087 projectTable->
Save( projectTableFn.GetFullPath() );
1091 msg.Printf(
_(
"Error saving project-specific library table:\n\n%s" ), ioe.
What() );
1092 wxMessageBox( msg,
_(
"File Save Error" ), wxOK | wxICON_ERROR );
1097 schEditor->SyncView();
1102 if( !currentLib.empty() && projectTable && !projectTable->
HasLibrary( currentLib,
true ) )
1104 symbolEditor->SetCurLib( wxEmptyString );
1105 symbolEditor->emptyScreen();
1108 symbolEditor->SyncLibraries(
true );
1109 symbolEditor->ThawLibraryTree();
1110 symbolEditor->RefreshLibraryTree();
1114 symbolViewer->ReCreateLibList();
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
bool m_ProjectTableChanged
void InstallPanel(wxPanel *aPanel)
bool m_GlobalTableChanged
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
wxString m_lastSymbolLibDir
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.
virtual void paste_text(const wxString &cb_text)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
void SetKiway(wxWindow *aDest, KIWAY *aKiway)
It is only used for debugging, since "this" is not a wxWindow*.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
static unsigned FindIllegalLibraryNameChar(const UTF8 &aLibraryName)
Looks for characters that are illegal in library nicknames.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
void SetValue(int aRow, int aCol, const wxString &aValue) override
bool AppendRows(size_t aNumRows=1) override
int GetNumberRows() override
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
LIB_TABLE * GetParent() const
void SetParent(LIB_TABLE *aParent)
const wxString & GetNickName() const
LIB_TABLE_ROW * clone() const
bool GetIsEnabled() const
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
void Clear()
Delete all rows.
unsigned GetCount() const
Get the number of rows contained in the table.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
Class PANEL_SYM_LIB_TABLE_BASE.
STD_BITMAP_BUTTON * m_browse_button
STD_BITMAP_BUTTON * m_move_up_button
STD_BITMAP_BUTTON * m_delete_button
STD_BITMAP_BUTTON * m_move_down_button
STD_BITMAP_BUTTON * m_append_button
WX_GRID * m_path_subs_grid
Dialog to show and edit symbol library tables.
void OnUpdateUI(wxUpdateUIEvent &event) override
void moveUpHandler(wxCommandEvent &event) override
virtual ~PANEL_SYM_LIB_TABLE()
SYMBOL_LIB_TABLE * m_projectTable
static size_t m_pageNdx
Remember the last notebook page selected.
void deleteRowHandler(wxCommandEvent &event) override
wxString m_lastProjectLibDir
void browseLibrariesHandler(wxCommandEvent &event) override
SYMBOL_LIB_TABLE_GRID * cur_model() const
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)
bool verifyTables()
Trim important fields, removes blank row entries, and checks for duplicates.
void adjustPathSubsGridColumns(int aWidth)
bool convertLibrary(const wxString &aLibrary, const wxString &legacyFilepath, const wxString &newFilepath)
SYMBOL_LIB_TABLE_GRID * global_model() const
SYMBOL_LIB_TABLE * m_globalTable
void onSizeGrid(wxSizeEvent &event) override
void onConvertLegacyLibraries(wxCommandEvent &event) override
SYMBOL_LIB_TABLE_GRID * project_model() const
void moveDownHandler(wxCommandEvent &event) override
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
bool TransferDataFromWindow() override
void appendRowHandler(wxCommandEvent &event) override
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Container for project specific data.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Schematic editor (Eeschema) main window.
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
static const wxString GetLibraryFileExtension(SCH_FILE_T aFileType)
Return the symbol library file extension (if any) for aFileType.
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
virtual void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
The symbol library editor main window.
DIALOG_EDIT_LIBRARY_TABLES * m_dialog
SYMBOL_GRID_TRICKS(DIALOG_EDIT_LIBRARY_TABLES *aParent, WX_GRID *aGrid)
virtual void paste_text(const wxString &cb_text) override
handle specialized clipboard text, with leading "(sym_lib_table" or spreadsheet formatted text.
Build a wxGridTableBase by wrapping an SYMBOL_LIB_TABLE object.
void SetValue(int aRow, int aCol, const wxString &aValue) override
LIB_TABLE_ROW * at(size_t aIndex) override
LIB_TABLE_ROWS_ITER erase(LIB_TABLE_ROWS_ITER aFirst, LIB_TABLE_ROWS_ITER aLast) override
LIB_TABLE_ROWS_ITER begin() override
LIB_TABLE_ROWS_ITER insert(LIB_TABLE_ROWS_ITER aIterator, LIB_TABLE_ROW *aRow) override
LIB_TABLE_ROW * makeNewRow() override
void push_back(LIB_TABLE_ROW *aRow) override
size_t size() const override
SYMBOL_LIB_TABLE_GRID(const SYMBOL_LIB_TABLE &aTableToEdit)
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
bool Refresh()
Attempt to reload the library.
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
static const wxString & GetSymbolLibTableFileName()
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
Symbol library viewer main window.
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...
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
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.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
This file is part of the common library.
@ ID_END_EESCHEMA_ID_LIST
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
@ FRAME_SCH_SYMBOL_EDITOR
wxString DatabaseLibFileWildcard()
wxString LegacySymbolLibFileWildcard()
wxString KiCadSymbolLibFileWildcard()
wxString AllSymbolLibFilesWildcard()
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
@ ID_PANEL_SYM_LIB_LEGACY
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
A filename or source description, a problem input line, a line number, a byte offset,...
Container that describes file type info for the add a library options.
bool m_IsFile
Whether the library is a folder or a file.
wxString m_Description
Description shown in the file picker dialog.
wxString m_FileFilter
Filter used for file pickers if m_IsFile is true.
SCH_IO_MGR::SCH_FILE_T m_Plugin
wxString m_FolderSearchExtension
In case of folders it stands for extensions of files stored inside.
Definition of file extensions used in Kicad.