25#include <wx/filedlg.h>
83 virtual wxDirTraverseResult
OnFile(
const wxString& aFileName )
override
85 wxFileName file( aFileName );
89 if( file.GetExt().IsSameAs( ext,
false ) )
93 return wxDIR_CONTINUE;
96 virtual wxDirTraverseResult
OnOpenError(
const wxString& aOpenErrorName )
override
104 virtual wxDirTraverseResult
OnDir(
const wxString& aDirName )
override
107 return wxDIR_CONTINUE;
112 for( std::pair<const wxString, int>& foundDirsPair :
m_foundDirs )
113 aPathArray.Add( foundDirsPair.first );
118 for( std::pair<const wxString, int>& failedDirsPair :
m_failedDirs )
119 aPathArray.Add( failedDirsPair.first );
138 wxString* aMRUDirectory,
const wxString& aProjectPath,
147 void SetValue(
int aRow,
int aCol,
const wxString& aValue )
override
149 wxCHECK( aRow < (
int)
size(), );
175 wxString
filter =
_(
"Design Block Library Tables" );
180 filter << wxString::Format(
_(
" (%s)|%s" ), wxFileSelectorDefaultWildcardStr,
181 wxFileSelectorDefaultWildcardStr );
186 if( tableRow.
Type().IsEmpty() )
187 return wxEmptyString;
191 return wxEmptyString;
198 return wxEmptyString;
223 if( aRow < tbl->GetNumberRows() )
226 const wxString& options = row.
Options();
227 wxString
result = options;
228 std::map<std::string, UTF8> choices;
234 pi->GetLibraryOptions( &choices );
255 wxMessageBox(
_(
"Unable to load library table." ) );
267 return wxT(
"(design_block_lib_table" );
282 wxString tabTitle = aTitle;
284 if( aTable->IsReadOnly() )
285 tabTitle += wxS(
" " ) +
_(
"(read-only)" );
287 for(
int ii = 2; ii < (int)
m_notebook->GetPageCount(); ++ii )
289 wxString candidate =
m_notebook->GetPageText( ii );
291 if( candidate.EndsWith(
" *" ) )
292 candidate = candidate.Left( candidate.Length() - 2 );
294 if( candidate == tabTitle )
298 for(
int attempts = 0; attempts < 3; ++attempts )
306 AddTable( aTable.get(), tabTitle,
true );
310 for(
int attempts = 0; attempts < 3; ++attempts )
318 wxString projectPath =
m_project->GetProjectPath();
324 if(
table->Path().StartsWith( projectPath ) )
333 wxString* lastGlobalLibDir =
nullptr;
337 if( cfg->m_lastDesignBlockLibDir.IsEmpty() )
340 lastGlobalLibDir = &cfg->m_lastDesignBlockLibDir;
344 lastGlobalLibDir, wxEmptyString,
367 int prevWidth =
grid->GetColSize( aCol );
369 grid->AutoSizeColumn( aCol,
false );
370 grid->SetColSize( aCol, std::max( prevWidth,
grid->GetColSize( aCol ) ) );
379 if(
grid->GetNumberRows() > 0 )
382 grid->SelectRow( 0 );
405 wxASSERT(
table.has_value() );
412 if( projectTable.has_value() )
413 AddTable( projectTable.value(),
_(
"Project Specific Libraries" ),
false );
450 if( desc.m_IsFile && !desc.m_FileExtensions.empty() )
452 entryStr << wxString::Format( wxS(
" (%s)" ),
JoinExtensions( desc.m_FileExtensions ) );
454 else if( !desc.m_IsFile && !desc.m_ExtensionsInDir.empty() )
456 midPart = wxString::Format(
_(
"folder with %s files" ),
JoinExtensions( desc.m_ExtensionsInDir ) );
457 entryStr << wxString::Format( wxS(
" (%s)" ), midPart );
460 browseMenu->Append( type, entryStr );
527 for(
int page = 0 ; page < (int)
m_notebook->GetPageCount(); ++page )
532 [&](
int aRow,
int aCol )
538 grid->MakeCellVisible( aRow, 0 );
539 grid->SetGridCursor( aRow, aCol );
586 wxAuiNotebook* notebook = (wxAuiNotebook*) aEvent.GetEventObject();
587 wxWindow* page = notebook->GetPage( aEvent.GetSelection() );
591 if( panel->GetClosable() )
593 if( !panel->GetCanClose() )
607 if( !
cur_grid()->CommitPendingChanges() )
610 wxArrayInt selectedRows =
cur_grid()->GetSelectedRows();
612 if( selectedRows.empty() &&
cur_grid()->GetGridCursorRow() >= 0 )
613 selectedRows.push_back(
cur_grid()->GetGridCursorRow() );
615 wxArrayInt rowsToMigrate;
620 for(
int row : selectedRows )
625 if( type != kicadType && type != nestedTableType )
626 rowsToMigrate.push_back( row );
629 if( rowsToMigrate.size() <= 0 )
631 wxMessageBox(
_(
"Select one or more rows containing libraries to save as current KiCad format." ) );
636 if( rowsToMigrate.size() == 1 )
638 msg.Printf(
_(
"Save '%s' as current KiCad format and replace entry in table?" ),
643 msg.Printf(
_(
"Save %d libraries as current KiCad format and replace entries in table?" ),
644 (
int) rowsToMigrate.size() );
651 for(
int row : rowsToMigrate )
655 wxFileName legacyLib( resolvedPath );
657 if( !legacyLib.Exists() )
659 msg.Printf(
_(
"Library '%s' not found." ), relPath );
664 wxFileName newLib( resolvedPath );
666 newLib.SetName(
"" );
669 if( newLib.DirExists() )
671 msg.Printf(
_(
"Folder '%s' already exists. Do you want overwrite any existing design blocks?" ),
672 newLib.GetFullPath() );
674 switch( wxMessageBox( msg,
_(
"Migrate Library" ), wxYES_NO | wxCANCEL | wxICON_QUESTION,
m_parent ) )
678 case wxCANCEL:
return;
695 newLib.GetFullPath() ) );
703 if( !
cur_grid()->CommitPendingChanges() )
710 if( event.GetEventType() == wxEVT_BUTTON )
736 wxWindow* topLevelParent = wxGetTopLevelParent(
this );
740 wxFileDialog dlg( topLevelParent, title, *lastDir, wxEmptyString, fileDesc.
FileFilter(),
741 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
745 if( dlg.ShowModal() == wxID_CANCEL )
748 dlg.GetPaths( files );
749 *lastDir = dlg.GetDirectory();
753 wxDirDialog dlg( topLevelParent, title, *lastDir,
754 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST | wxDD_MULTIPLE );
756 if( dlg.ShowModal() == wxID_CANCEL )
759 dlg.GetPaths( files );
761 if( !files.IsEmpty() )
763 wxFileName first( files.front() );
764 *lastDir = first.GetPath();
773 bool addDuplicates =
false;
774 bool applyToAll =
false;
775 wxString warning =
_(
"Warning: Duplicate Nicknames" );
776 wxString msg =
_(
"An item nicknamed '%s' already exists." );
777 wxString detailedMsg =
_(
"One of the nicknames will need to be changed." );
779 for(
const wxString& filePath : files )
781 wxFileName fn( filePath );
788 if(
cur_model()->ContainsNickname( nickname ) )
794 _(
"Skip" ),
_(
"Add Anyway" ), &applyToAll ) == wxID_CANCEL;
797 doAdd = addDuplicates;
800 if( doAdd &&
cur_grid()->AppendRows( 1 ) )
802 int last_row =
cur_grid()->GetNumberRows() - 1;
812 if(
m_notebook->GetSelection() == 0 &&
path.Contains( wxT(
"${KIPRJMOD}" ) ) )
813 path = fn.GetFullPath();
819 if( !files.IsEmpty() )
848 if( !
cur_grid()->CommitPendingChanges() )
856 int firstNestedTable = 1;
860 if( globalTable.has_value() &&
get_model( 0 )->Table() != *globalTable.value() )
862 m_parent->m_GlobalTableChanged =
true;
865 globalTable.value()->
Save().map_error(
868 wxMessageBox(
_(
"Error saving global library table:\n\n" ) + aError.
message,
869 _(
"File Save Error" ), wxOK | wxICON_ERROR );
877 if( projectTable.has_value() &&
get_model( 1 )->Table().Path() == projectTable.value()->Path() )
879 firstNestedTable = 2;
881 if(
get_model( 1 )->Table() != *projectTable.value() )
883 m_parent->m_ProjectTableChanged =
true;
886 projectTable.value()->
Save().map_error(
889 wxMessageBox(
_(
"Error saving project library table:\n\n" ) + aError.
message,
890 _(
"File Save Error" ), wxOK | wxICON_ERROR );
896 for(
int ii = firstNestedTable; ii < (int)
m_notebook->GetPageCount(); ++ii )
913 wxRegEx re(
".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
914 wxASSERT( re.IsValid() );
916 std::set<wxString> unique;
921 for(
int page = 0 ; page < (int)
m_notebook->GetPageCount(); ++page )
925 for(
int row = 0; row <
model->GetNumberRows(); ++row )
929 while( re.Matches( uri ) )
931 wxString envvar = re.GetMatch( uri, 2 );
934 if( envvar.IsEmpty() )
935 envvar = re.GetMatch( uri, 4 );
938 unique.insert( envvar );
941 uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
955 for(
const wxString& evName : unique )
960 m_path_subs_grid->SetCellValue( row, 0, wxT(
"${" ) + evName + wxT(
"}" ) );
964 wxGetEnv( evName, &evValue );
996 std::string payload =
"";
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
static bool SupportsVisibilityColumn()
bool supportsVisibilityColumn() override
void openTable(const LIBRARY_TABLE_ROW &aRow) override
wxString getTablePreamble() override
void optionsEditor(int aRow) override
DESIGN_BLOCK_GRID_TRICKS(PANEL_DESIGN_BLOCK_LIB_TABLE *aPanel, WX_GRID *aGrid)
PANEL_DESIGN_BLOCK_LIB_TABLE * m_panel
@ KICAD_SEXP
S-expression KiCad file format.
@ DESIGN_BLOCK_FILE_UNKNOWN
0 is not a legal menu id on Mac
static const wxString ShowType(DESIGN_BLOCK_FILE_T aFileType)
static DESIGN_BLOCK_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
static DESIGN_BLOCK_FILE_T EnumFromStr(const wxString &aFileType)
static bool ConvertLibrary(std::map< std::string, UTF8 > *aOldFileProps, const wxString &aOldFilePath, const wxString &aNewFilePath)
Convert a design block library to the latest KiCad format.
static DESIGN_BLOCK_IO * FindPlugin(DESIGN_BLOCK_FILE_T aFileType)
static wxString GlobalPathEnvVariableName()
This class builds a wxGridTableBase by wrapping an DESIGN_BLOCK_LIB_TABLE object.
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxString getFileTypes(WX_GRID *aGrid, int aRow) override
const std::map< DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T, IO_BASE::IO_FILE_DESC > & m_supportedDesignBlockFiles
DESIGN_BLOCK_LIB_TABLE_GRID_DATA_MODEL(DIALOG_SHIM *aParent, WX_GRID *aGrid, const LIBRARY_TABLE &aTableToEdit, LIBRARY_MANAGER_ADAPTER *aAdapter, const wxArrayString &aPluginChoices, wxString *aMRUDirectory, const wxString &aProjectPath, const std::map< DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T, IO_BASE::IO_FILE_DESC > &aSupportedFiles)
bool m_ProjectTableChanged
void InstallPanel(wxPanel *aPanel, wxAuiNotebook *aNotebook)
bool m_GlobalTableChanged
An options editor in the form of a two column name/value spreadsheet like (table) UI.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
WX_GRID * m_grid
I don't own the grid, but he owns me.
void SetTooltipEnable(int aCol, bool aEnable=true)
Enable the tooltip for a column.
wxString m_lastDesignBlockLibDir
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, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
The interface used by the classes that actually can load IO plugins for the different parts of KiCad ...
static wxString ExpandURI(const wxString &aShortURI, const PROJECT &aProject)
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void ApplyLibOverrides(LIBRARY_TABLE &aTable)
Applies stored user overrides (disabled/hidden) to rows of a read-only table.
void LoadGlobalTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the global library tables in the given list, or all tables if no list is given
void ProjectChanged()
Notify all adapters that the project has changed.
void SetOptions(const wxString &aOptions)
const wxString & Type() const
static const wxString TABLE_TYPE_NAME
const wxString & URI() const
const wxString & Nickname() const
const wxString & Options() const
LIBRARY_RESULT< void > Save()
static std::map< std::string, UTF8 > ParseOptions(const std::string &aOptionsList)
void GetPaths(wxArrayString &aPathArray)
virtual wxDirTraverseResult OnOpenError(const wxString &aOpenErrorName) override
std::unordered_map< wxString, int > m_failedDirs
std::vector< std::string > m_searchExtensions
void GetFailedPaths(wxArrayString &aPathArray)
bool HasDirectoryOpenFailures()
LIBRARY_TRAVERSER(std::vector< std::string > aSearchExtensions, wxString aInitialDir)
std::unordered_map< wxString, int > m_foundDirs
virtual wxDirTraverseResult OnDir(const wxString &aDirName) override
virtual wxDirTraverseResult OnFile(const wxString &aFileName) override
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 LIBRARY_TABLE into wxGridTableBase so the resu...
virtual LIBRARY_TABLE_ROW & at(size_t aIndex)
virtual size_t size() const
void SetChangeCallback(std::function< void()> aCallback)
LIBRARY_TABLE_ROW & At(size_t aIndex)
void SetValue(int aRow, int aCol, const wxString &aValue) override
LIB_TABLE_GRID_DATA_MODEL(DIALOG_SHIM *aParent, WX_GRID *aGrid, const LIBRARY_TABLE &aTableToEdit, LIBRARY_MANAGER_ADAPTER *aAdapter, const wxArrayString &aPluginChoices, wxString *aMRUDirectory, const wxString &aProjectPath)
static void MoveUpHandler(WX_GRID *aGrid)
LIB_TABLE_GRID_TRICKS(WX_GRID *aGrid)
static void DeleteRowHandler(WX_GRID *aGrid)
static void AppendRowHandler(WX_GRID *aGrid, const wxString &aType)
static bool VerifyTable(WX_GRID *aGrid, bool aSupportsVisibilityColumn, std::function< void(int aRow, int aCol)> aErrorHandler)
static void MoveDownHandler(WX_GRID *aGrid)
static void AddTable(wxAuiNotebook *aNotebook, const wxString &aTitle, bool aClosable)
wxAuiNotebook * m_notebook
WX_GRID * m_path_subs_grid
STD_BITMAP_BUTTON * m_move_up_button
STD_BITMAP_BUTTON * m_delete_button
wxButton * m_migrate_libs_button
SPLIT_BUTTON * m_browseButton
STD_BITMAP_BUTTON * m_append_button
PANEL_DESIGN_BLOCK_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)
STD_BITMAP_BUTTON * m_move_down_button
Dialog to show and edit symbol library tables.
void moveUpHandler(wxCommandEvent &event) override
void onMigrateLibraries(wxCommandEvent &event) override
void onNotebookPageCloseRequest(wxAuiNotebookEvent &aEvent)
std::vector< std::shared_ptr< LIBRARY_TABLE > > m_nestedTables
void adjustPathSubsGridColumns(int aWidth)
wxAuiNotebook * GetNotebook() const
bool TransferDataFromWindow() override
void browseLibrariesHandler(wxCommandEvent &event)
void populateEnvironReadOnlyTable()
Populate the readonly environment variable table with names and values by examining all the full_uri ...
WX_GRID * cur_grid() const
std::map< DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T, IO_BASE::IO_FILE_DESC > m_supportedDesignBlockFiles
void moveDownHandler(wxCommandEvent &event) override
DIALOG_EDIT_LIBRARY_TABLES * m_parent
void onNotebookPageChangeRequest(wxAuiNotebookEvent &aEvent)
wxArrayString m_pluginChoices
DESIGN_BLOCK_LIB_TABLE_GRID_DATA_MODEL * get_model(int aPage) const
bool m_suppressNotebookPageEvents
wxString m_lastProjectLibDir
void appendRowHandler(wxCommandEvent &event) override
PANEL_DESIGN_BLOCK_LIB_TABLE(DIALOG_EDIT_LIBRARY_TABLES *aParent, PROJECT *aProject)
WX_GRID * get_grid(int aPage) const
void populatePluginList()
~PANEL_DESIGN_BLOCK_LIB_TABLE() override
void onSizeGrid(wxSizeEvent &event) override
void deleteRowHandler(wxCommandEvent &event) override
void AddTable(LIBRARY_TABLE *table, const wxString &aTitle, bool aClosable)
void OpenTable(const std::shared_ptr< LIBRARY_TABLE > &table, const wxString &aTitle)
bool verifyTables()
Trim important fields, removes blank row entries, and checks for duplicates.
DESIGN_BLOCK_LIB_TABLE_GRID_DATA_MODEL * cur_model() const
static wxString GetDefaultUserDesignBlocksPath()
Gets the default path we point users to create projects.
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
virtual LIBRARY_MANAGER & GetLibraryManager() const
Container for project specific data.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString JoinExtensions(const std::vector< std::string > &aExts)
Join a list of file extensions for use in a file dialog.
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 DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Helper functions to substitute paths with environmental variables.
Functions related to environment variables, including help functions.
static const std::string KiCadDesignBlockLibPathExtension
static const std::string DesignBlockLibraryTableFileName
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
void InvokeEditDesignBlockLibTable(KIWAY *aKiway, wxWindow *aParent)
PGM_BASE & Pgm()
The global program "get" accessor.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
T * GetAppSettings(const char *aFilename)
std::vector< FAB_LAYER_COLOR > dummy
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
Container that describes file type info.
bool m_IsFile
Whether the library is a folder or a file.
wxString FileFilter() const
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.
DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T m_Plugin
wxString m_FolderSearchExtension
In case of folders it stands for extensions of files stored inside.
wxString result
Test unit parsing edge cases and error handling.
Definition of file extensions used in Kicad.