39#include <wx/filedlg.h>
46#include <lib_table_lexer.h>
101static const std::map<int, SUPPORTED_FILE_TYPE>&
fileTypes()
110 static const std::map<int, SUPPORTED_FILE_TYPE>
fileTypes =
114 wxT(
"KiCad (folder with .kicad_mod files)" ), wxT(
"" ),
143 wxT(
"Geda (folder with *.fp files)" ), wxT(
"" ),
167 virtual wxDirTraverseResult
OnFile(
const wxString& aFileName )
override
169 wxFileName file( aFileName );
174 return wxDIR_CONTINUE;
177 virtual wxDirTraverseResult
OnOpenError(
const wxString& aOpenErrorName )
override
188 virtual wxDirTraverseResult
OnDir(
const wxString& aDirName )
override
191 return wxDIR_CONTINUE;
196 for( std::pair<const wxString, int>& foundDirsPair :
m_foundDirs )
197 aPathArray.Add( foundDirsPair.first );
202 for( std::pair<const wxString, int>& failedDirsPair :
m_failedDirs )
203 aPathArray.Add( failedDirsPair.first );
236 return m_rows.insert( aIterator, aRow );
243 return m_rows.erase( aFirst, aLast );
274 wxString result = options;
284 if( options != result )
297 size_t ndx = cb_text.find(
"(fp_lib_table" );
299 if( ndx != std::string::npos )
305 LIB_TABLE_LEXER lexer( &slr );
311 tmp_tbl.
Parse( &lexer );
325 for(
unsigned i = 0; i < tmp_tbl.
GetCount(); ++i )
329 m_grid->AutoSizeColumns(
false );
336 m_grid->AutoSizeColumns(
false );
344 FP_LIB_TABLE* aProject,
const wxString& aProjectTblPath,
345 const wxString& aProjectBasePath ) :
348 m_project( aProject ),
349 m_projectBasePath( aProjectBasePath ),
357 wxArrayString choices;
377 [&](
WX_GRID* aGrid,
int aCol )
379 int prevWidth = aGrid->GetColSize( aCol );
381 aGrid->AutoSizeColumn( aCol,
false );
382 aGrid->SetColSize( aCol, std::max( prevWidth, aGrid->GetColSize( aCol ) ) );
389 aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
394 aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
396 wxGridCellAttr* attr;
398 attr =
new wxGridCellAttr;
403 aGrid->SetColAttr(
COL_URI, attr );
405 attr =
new wxGridCellAttr;
406 attr->SetEditor(
new wxGridCellChoiceEditor( choices ) );
407 aGrid->SetColAttr(
COL_TYPE, attr );
409 attr =
new wxGridCellAttr;
410 attr->SetRenderer(
new wxGridCellBoolRenderer() );
427 if( aGrid->GetNumberRows() > 0 )
428 aGrid->SelectRow( 0 );
513 for(
int r = 0; r < model->GetNumberRows(); )
515 wxString nick = model->GetValue( r,
COL_NICKNAME ).Trim(
false ).Trim();
516 wxString uri = model->GetValue( r,
COL_URI ).Trim(
false ).Trim();
517 unsigned illegalCh = 0;
522 msg =
_(
"A library table row nickname and path cells are empty." );
524 msg =
_(
"A library table row nickname cell is empty." );
526 msg =
_(
"A library table row path cell is empty." );
528 wxMessageDialog badCellDlg(
this, msg,
_(
"Invalid Row Definition" ),
529 wxYES_NO | wxCENTER | wxICON_QUESTION | wxYES_DEFAULT );
530 badCellDlg.SetExtendedMessage(
_(
"Empty cells will result in all rows that are "
531 "invalid to be removed from the table." ) );
532 badCellDlg.SetYesNoLabels( wxMessageDialog::ButtonLabel(
_(
"Remove Invalid Cells" ) ),
533 wxMessageDialog::ButtonLabel(
_(
"Cancel Table Update" ) ) );
535 if( badCellDlg.ShowModal() == wxID_NO )
542 model->DeleteRows( r, 1 );
546 msg = wxString::Format(
_(
"Illegal character '%c' in nickname '%s'." ),
557 wxMessageDialog errdlg(
this, msg,
_(
"Library Nickname Error" ) );
565 model->SetValue( r,
COL_URI, uri );
581 for(
int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
585 for(
int r2 = r1 + 1; r2 < model->GetNumberRows(); ++r2 )
591 msg = wxString::Format(
_(
"Multiple libraries cannot share the same "
592 "nickname ('%s')." ),
603 wxMessageDialog errdlg(
this, msg,
_(
"Library Nickname Error" ) );
629 int last_row =
m_cur_grid->GetNumberRows() - 1;
653 wxArrayInt selectedRows =
m_cur_grid->GetSelectedRows();
654 wxGridCellCoordsArray cells =
m_cur_grid->GetSelectedCells();
655 wxGridCellCoordsArray blockTopLeft =
m_cur_grid->GetSelectionBlockTopLeft();
656 wxGridCellCoordsArray blockBotRight =
m_cur_grid->GetSelectionBlockBottomRight();
659 for(
unsigned ii = 0; ii < cells.GetCount(); ii++ )
660 selectedRows.Add( cells[ii].GetRow() );
663 if( !blockTopLeft.IsEmpty() && !blockBotRight.IsEmpty() )
665 for(
int i = blockTopLeft[0].GetRow(); i <= blockBotRight[0].GetRow(); ++i )
666 selectedRows.Add( i );
670 if( selectedRows.size() == 0 &&
m_cur_grid->GetGridCursorRow() >= 0 )
671 selectedRows.Add(
m_cur_grid->GetGridCursorRow() );
673 if( selectedRows.size() == 0 )
679 std::sort( selectedRows.begin(), selectedRows.end() );
684 for(
int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
686 int row = selectedRows[ii];
688 if( row != last_row )
695 if(
m_cur_grid->GetNumberRows() > 0 && curRow >= 0 )
711 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
715 tbl->
m_rows.insert( tbl->
m_rows.begin() + curRow, move_me.release() );
720 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow, 0 );
721 tbl->GetView()->ProcessTableMessage( msg );
739 if(
unsigned( curRow + 1 ) < tbl->
m_rows.size() )
741 boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
745 tbl->
m_rows.insert( tbl->
m_rows.begin() + curRow, move_me.release() );
750 wxGridTableMessage msg( tbl, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, curRow - 1, 0 );
751 tbl->GetView()->ProcessTableMessage( msg );
765 std::map<int, SUPPORTED_FILE_TYPE>::const_iterator fileTypeIt;
769 if( event.GetEventType() == wxEVT_BUTTON )
776 fileTypeIt =
fileTypes().find( event.GetId() );
781 wxLogWarning( wxT(
"File type selection event received but could not find the file type "
794 title.Printf(
_(
"Select %s Library" ),
fileType.m_Description );
803 wxFileDialog dlg(
this, title, openDir, wxEmptyString,
fileType.m_FileFilter,
804 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
806 int result = dlg.ShowModal();
808 if( result == wxID_CANCEL )
811 dlg.GetPaths( files );
820#if wxCHECK_VERSION( 3, 1, 4 )
821 wxDirDialog dlg(
nullptr, title, openDir,
822 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST | wxDD_MULTIPLE );
824 int result = dlg.ShowModal();
826 if( result == wxID_CANCEL )
829 dlg.GetPaths( files );
831 wxDirDialog dlg(
nullptr, title, openDir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
833 int result = dlg.ShowModal();
835 if( result == wxID_CANCEL )
839 if(
fileType.m_FolderSearchExtension !=
"" )
841 wxDir rootDir( dlg.GetPath() );
844 rootDir.Traverse( traverser );
850 wxArrayString failedDirs;
852 wxString detailedMsg =
_(
"The following directories could not be opened: \n" );
854 for(
const wxString&
path : failedDirs )
855 detailedMsg <<
path << wxT(
"\n" );
863 files.Add( dlg.GetPath() );
867 if( !files.IsEmpty() )
869 wxFileName first( files.front() );
883 bool addDuplicates =
false;
884 bool applyToAll =
false;
885 wxString warning =
_(
"Warning: Duplicate Nicknames" );
886 wxString msg =
_(
"A library nicknamed '%s' already exists." );
887 wxString detailedMsg =
_(
"One of the nicknames will need to be changed after "
888 "adding this library." );
890 for(
const wxString& filePath : files )
892 wxFileName fn( filePath );
899 if(
cur_model()->ContainsNickname( nickname ) )
904 addDuplicates =
OKOrCancelDialog(
this, warning, wxString::Format( msg, nickname ),
905 detailedMsg,
_(
"Skip" ),
_(
"Add Anyway" ),
906 &applyToAll ) == wxID_CANCEL;
909 doAdd = addDuplicates;
914 int last_row =
m_cur_grid->GetNumberRows() - 1;
925 if(
m_pageNdx == 0 &&
path.Contains( wxT(
"${KIPRJMOD}" ) ) )
926 path = fn.GetFullPath();
932 if( !files.IsEmpty() )
934 int new_row =
m_cur_grid->GetNumberRows() - 1;
998 wxRegEx re(
".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
999 wxASSERT( re.IsValid() );
1001 std::set< wxString > unique;
1011 for(
int row = 0; row < tbl->GetNumberRows(); ++row )
1013 wxString uri = tbl->GetValue( row,
COL_URI );
1015 while( re.Matches( uri ) )
1017 wxString envvar = re.GetMatch( uri, 2 );
1020 if( envvar.IsEmpty() )
1021 envvar = re.GetMatch( uri, 4 );
1024 unique.insert( envvar );
1027 uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
1040 for(
const wxString& evName : unique )
1045 m_path_subs_grid->SetCellValue( row, 0, wxT(
"${" ) + evName + wxT(
"}" ) );
1049 wxGetEnv( evName, &evValue );
1080 projectTable =
nullptr;
1083 projectTable, projectTablePath,
1086 if( dlg.ShowModal() == wxID_CANCEL )
1093 globalTable->
Save( globalTablePath );
1097 msg.Printf(
_(
"Error saving global library table:\n\n%s" ), ioe.
What() );
1098 wxMessageBox( msg,
_(
"File Save Error" ), wxOK | wxICON_ERROR );
1106 projectTable->
Save( projectTablePath );
1110 msg.Printf(
_(
"Error saving project-specific library table:\n\n%s" ), ioe.
What() );
1111 wxMessageBox( msg,
_(
"File Save Error" ), wxOK | wxICON_ERROR );
1115 std::string payload =
"";
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
DIALOG_PLUGIN_OPTIONS is an options editor in the form of a two column name/value spreadsheet like (t...
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
void paste_text(const wxString &cb_text) override
handle specialized clipboard text, with leading "(fp_lib_table", OR spreadsheet formatted text.
DIALOG_EDIT_LIBRARY_TABLES * m_dialog
FP_GRID_TRICKS(DIALOG_EDIT_LIBRARY_TABLES *aParent, WX_GRID *aGrid)
void optionsEditor(int aRow) override
This class builds a wxGridTableBase by wrapping an FP_LIB_TABLE object.
size_t size() const override
FP_LIB_TABLE_GRID(const FP_LIB_TABLE &aTableToEdit)
LIB_TABLE_ROWS_ITER begin() override
LIB_TABLE_ROWS_ITER erase(LIB_TABLE_ROWS_ITER aFirst, LIB_TABLE_ROWS_ITER aLast) override
LIB_TABLE_ROW * makeNewRow() override
LIB_TABLE_ROW * at(size_t aIndex) override
void push_back(LIB_TABLE_ROW *aRow) override
LIB_TABLE_ROWS_ITER insert(LIB_TABLE_ROWS_ITER aIterator, LIB_TABLE_ROW *aRow) override
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
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 wxString GetGlobalTableFileName()
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()
static const wxString ShowType(PCB_FILE_T aFileType)
Return a brief name for a plugin given aFileType enum.
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
@ KICAD_SEXP
S-expression Pcbnew file format.
@ GEDA_PCB
Geda PCB file formats.
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
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 void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Traverser implementation that looks to find any and all "folder" libraries by looking for files with ...
void GetPaths(wxArrayString &aPathArray)
wxString m_searchExtension
virtual wxDirTraverseResult OnOpenError(const wxString &aOpenErrorName) override
std::unordered_map< wxString, int > m_failedDirs
void GetFailedPaths(wxArrayString &aPathArray)
bool HasDirectoryOpenFailures()
LIBRARY_TRAVERSER(wxString aSearchExtension, wxString aInitialDir)
std::unordered_map< wxString, int > m_foundDirs
virtual wxDirTraverseResult OnDir(const wxString &aDirName) override
virtual wxDirTraverseResult OnFile(const wxString &aFileName) override
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 '_'.
This abstract base class mixes any object derived from LIB_TABLE into wxGridTableBase so the result c...
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.
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
virtual const wxString GetType() const =0
Return the type of library represented by this row.
const wxString & GetNickName() const
LIB_TABLE_ROW * clone() const
void SetOptions(const wxString &aOptions)
Change the library options strings.
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 reindex(bool aForce)
Rebuilds the m_nickIndex.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
Class PANEL_FP_LIB_TABLE_BASE.
STD_BITMAP_BUTTON * m_move_up_button
WX_GRID * m_path_subs_grid
STD_BITMAP_BUTTON * m_append_button
STD_BITMAP_BUTTON * m_move_down_button
STD_BITMAP_BUTTON * m_delete_button
SPLIT_BUTTON * m_browseButton
Dialog to show and edit symbol library tables.
bool verifyTables()
Trim important fields, removes blank row entries, and checks for duplicates.
void onSizeGrid(wxSizeEvent &event) override
void moveUpHandler(wxCommandEvent &event) override
void adjustPathSubsGridColumns(int aWidth)
FP_LIB_TABLE_GRID * cur_model() const
FP_LIB_TABLE_GRID * project_model() const
void moveDownHandler(wxCommandEvent &event) override
FP_LIB_TABLE_GRID * global_model() const
wxString m_lastProjectLibDir
void populateEnvironReadOnlyTable()
Populate the readonly environment variable table with names and values by examining all the full_uri ...
~PANEL_FP_LIB_TABLE() override
void deleteRowHandler(wxCommandEvent &event) override
void browseLibrariesHandler(wxCommandEvent &event)
bool TransferDataFromWindow() override
wxString m_projectBasePath
DIALOG_EDIT_LIBRARY_TABLES * m_parent
void OnUpdateUI(wxUpdateUIEvent &event) override
void appendRowHandler(wxCommandEvent &event) override
PANEL_FP_LIB_TABLE(DIALOG_EDIT_LIBRARY_TABLES *aParent, FP_LIB_TABLE *aGlobal, const wxString &aGlobalTblPath, FP_LIB_TABLE *aProject, const wxString &aProjectTblPath, const wxString &aProjectBasePath)
static wxString GetDefaultUserFootprintsPath()
Gets the default path we point users to create projects.
wxString m_lastFootprintLibDir
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
virtual void FootprintLibOptions(STRING_UTF8_MAP *aListToAppendTo) const
Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
A name/value tuple with unique names and optional values.
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.
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.
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.
This file is part of the common library.
FP_LIB_TABLE GFootprintTable
The global footprint library table.
Declaration of the eda_3d_viewer class.
#define KICAD7_3DMODEL_DIR
A variable name whose value holds the path of 3D shape files.
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
const std::string KiCadFootprintLibPathExtension
const std::string KiCadFootprintFileExtension
const std::string GedaPcbFootprintLibFileExtension
wxString EagleFootprintLibPathWildcard()
wxString AltiumFootprintLibPathWildcard()
wxString CadstarPcbArchiveFileWildcard()
wxString LegacyFootprintLibPathWildcard()
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
@ ID_PANEL_FPLIB_ADD_EAGLE6
@ ID_PANEL_FPLIB_ADD_KICADMOD
@ ID_PANEL_FPLIB_ADD_GEDA
@ ID_PANEL_FPLIB_ADD_ALTIUM
@ ID_PANEL_FPLIB_ADD_KICADLEGACY
@ ID_PANEL_FPLIB_ADD_CADSTAR
static const std::map< int, SUPPORTED_FILE_TYPE > & fileTypes()
Map with event id as the key to supported file types that will be listed for the add a library option...
void InvokePcbLibTableEditor(KIWAY *aKiway, wxWindow *aCaller)
Function InvokePcbLibTableEditor shows the modal DIALOG_FP_LIB_TABLE for purposes of editing the glob...
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
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.
IO_MGR::PCB_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.