39#include <wx/snglinst.h>
58#include <nlohmann/json.hpp>
79#include <wx/tokenzr.h>
112 using json = nlohmann::json;
116 json input = json::parse( aFilterJson.ToStdString() );
118 int pinCount = input.value(
"pin_count", 0 );
119 bool zeroFilters = input.value(
"zero_filters",
true );
120 int maxResults = input.value(
"max_results", 400 );
122 std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> filterMatchers;
124 if( input.contains(
"filters" ) && input[
"filters"].is_array() )
126 for(
const auto& f : input[
"filters"] )
130 wxString pattern = wxString::FromUTF8( f.get<std::string>() );
131 auto matcher = std::make_unique<EDA_PATTERN_MATCH_WILDCARD_ANCHORED>();
132 matcher->SetPattern( pattern.Lower() );
133 filterMatchers.push_back( std::move( matcher ) );
138 bool hasFilters = ( pinCount > 0 || !filterMatchers.empty() );
140 if( zeroFilters && !hasFilters )
147 wxWindow* focus = wxWindow::FindFocus();
148 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
174 std::vector<FOOTPRINT*> footprints = adapter->
GetFootprints( nickname,
true );
186 if( fpPadCount != pinCount )
191 if( !filterMatchers.empty() )
193 bool matches =
false;
195 for(
const auto& matcher : filterMatchers )
200 if( matcher->GetPattern().Contains( wxS(
":" ) ) )
201 name = fp->GetFPID().GetLibNickname().wx_str().Lower() + wxS(
":" );
203 name += fp->GetFPID().GetLibItemName().wx_str().Lower();
205 if( matcher->Find(
name ) )
216 wxString libId = fp->GetFPID().Format();
217 output.push_back( libId.ToStdString() );
219 if( ++count >= maxResults )
223 if( count >= maxResults )
227 return wxString::FromUTF8(
output.dump() );
229 catch(
const std::exception& )
240static int pcbnewMergeExport(
int aKind,
const wxString& aAncestor,
const wxString& aOurs,
241 const wxString& aTheirs,
const wxString& aOutput,
bool aInteractive,
242 bool aSingleFile, REPORTER* aReporter );
244 const wxString& aLabelA,
const wxString& aLabelB,
245 wxWindow* aParent,
REPORTER* aReporter );
259 void Reset()
override;
281 return new FOOTPRINT_EDIT_FRAME( aKiway, aParent );
284 return new FOOTPRINT_VIEWER_FRAME( aKiway, aParent );
287 return new FOOTPRINT_CHOOSER_FRAME( aKiway, aParent );
290 return new FOOTPRINT_WIZARD_FRAME( aKiway, aParent,
FRAME_T( aClassId ) );
297 DIALOG_CONFIGURE_PATHS dlg( aParent );
302 dlg.SetKiway( &dlg, aKiway );
305 if( dlg.ShowQuasiModal() == wxID_OK )
386 return new PANEL_FP_EDITOR_GRAPHICS_DEFAULTS( aParent,
this );
397 std::vector<TOOL_ACTION*> actions;
398 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
401 actions.push_back( action );
404 controls.push_back( control );
410 return new PANEL_FP_EDITOR_COLOR_SETTINGS( aParent );
429 return new PANEL_GRID_SETTINGS( aParent,
this, frame, cfg,
FRAME_PCB_EDITOR );
449 return new PANEL_EDIT_OPTIONS( aParent,
this, frame,
false );
454 BOARD* board =
nullptr;
458 board =
static_cast<PCB_EDIT_FRAME*
>( boardProvider )->GetBoard();
460 return new PANEL_PCBNEW_COLOR_SETTINGS( aParent, board );
468 std::vector<TOOL_ACTION*> actions;
469 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
472 actions.push_back( action );
475 controls.push_back( control );
477 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_EDITOR, actions, controls );
481 return new PANEL_PCBNEW_ACTION_PLUGINS( aParent );
484 return new PANEL_3D_DISPLAY_OPTIONS( aParent );
487 return new PANEL_3D_OPENGL_OPTIONS( aParent );
490 return new PANEL_3D_RAYTRACING_OPTIONS( aParent );
497 std::vector<TOOL_ACTION*> actions;
498 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
501 actions.push_back( action );
504 controls.push_back( control );
506 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_DISPLAY3D, actions, controls );
536 wxWindow* focus = wxWindow::FindFocus();
537 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
578 void SaveFileAs(
const wxString& aProjectBasePath,
const wxString& aSrcProjectName,
579 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
580 const wxString& aSrcFilePath, wxString& aErrors )
override;
588 wxString* aError )
override;
592 wxString* aError )
override;
622 const wxString& aTheirs,
const wxString& aOutput,
bool aInteractive,
623 bool aSingleFile,
REPORTER* aReporter )
626 aOurs, aTheirs, aOutput, aInteractive, aSingleFile,
632 const wxString& aLabelA,
const wxString& aLabelB,
633 wxWindow* aParent,
REPORTER* aReporter )
636 aFileB, aLabelA, aLabelB, aParent, aReporter );
681 m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>( aKiway );
713 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
714 const wxString& aSrcFilePath, wxString& aErrors )
716 wxFileName destFile( aSrcFilePath );
717 wxString destPath = destFile.GetPathWithSep();
718 wxUniChar pathSep = wxFileName::GetPathSeparator();
719 wxString ext = destFile.GetExt();
721 if( destPath.StartsWith( aProjectBasePath + pathSep ) )
722 destPath.Replace( aProjectBasePath, aNewProjectBasePath,
false );
724 wxString srcProjectFootprintLib = pathSep + aSrcProjectName + wxT(
".pretty" ) + pathSep;
725 wxString newProjectFootprintLib = pathSep + aNewProjectName + wxT(
".pretty" ) + pathSep;
727 destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib,
true );
729 destFile.SetPath( destPath );
734 if( destFile.GetName() == aSrcProjectName )
735 destFile.SetName( aNewProjectName );
738 [&](
const std::string& token, wxString& value )
740 if( token ==
"sheetfile" )
742 for( const wxString extension : { wxT(
".sch" ), wxT(
".kicad_sch" ) } )
744 if( value == aSrcProjectName + extension )
746 value = aNewProjectName + extension;
749 else if( value == aProjectBasePath +
"/" + aSrcProjectName + extension )
751 value = aNewProjectBasePath +
"/" + aNewProjectName + extension;
754 else if( value.StartsWith( aProjectBasePath ) )
756 value.Replace( aProjectBasePath, aNewProjectBasePath, false );
768 if( destFile.GetName() == aSrcProjectName )
769 destFile.SetName( aNewProjectName );
771 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
777 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
783 else if( ext == wxT(
"rpt" ) )
789 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
793 wxFileName libTableFn( aSrcFilePath );
795 libTable.SetPath( destFile.GetFullPath() );
798 for( LIBRARY_TABLE_ROW& row : libTable.Rows() )
800 wxString uri = row.URI();
802 uri.Replace( wxT(
"/" ) + aSrcProjectName + wxT(
".pretty" ),
803 wxT(
"/" ) + aNewProjectName + wxT(
".pretty" ) );
808 libTable.Save().map_error(
809 [&](
const LIBRARY_ERROR& aError )
813 if( !aErrors.empty() )
814 aErrors += wxT(
"\n" );
816 msg.Printf(
_(
"Cannot copy file '%s'." ), destFile.GetFullPath() );
822 wxFAIL_MSG( wxT(
"Unexpected filetype for Pcbnew::SaveFileAs()" ) );
829 return m_jobHandler->RunJob( aJob, aReporter, aProgressReporter );
869 wxCHECK( aServer,
false );
871 if( aPath.IsEmpty() )
874 *aError = wxS(
"No path specified to open" );
888 if( fpid.
Parse( aLibIdStr ) >= 0 )
891 *aError = wxString::Format( wxS(
"Invalid footprint LIB_ID: %s" ), aLibIdStr );
896 wxFileName projectPath( aProjectPath );
897 projectPath.MakeAbsolute();
901 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
903 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aProjectPath );
911 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aProjectPath );
916 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> newContext;
928 *aError = wxString::Format( wxS(
"Footprint not found: %s" ), aLibIdStr );
933 newContext = std::make_shared<HEADLESS_FOOTPRINT_CONTEXT>(
939 *aError = wxString::Format( wxS(
"Failed to load footprint: %s" ), aLibIdStr );
956 wxFileName projectPath( aPath );
963 projectPath.MakeAbsolute();
972 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
974 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aPath );
982 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aPath );
987 wxFileName boardPath( projectPath );
990 if( !boardPath.FileExists() )
993 *aError = wxString::Format( wxS(
"File not found: %s" ), aPath );
1004 *aError = wxString::Format( wxS(
"%s is not a recognized file type" ), aPath );
1009 std::shared_ptr<HEADLESS_PCB_CONTEXT> newContext;
1018 *aError = wxS(
"Failed to load board" );
1023 newContext = std::make_shared<HEADLESS_PCB_CONTEXT>( std::move( loadedBoard ),
project,
1029 *aError = wxString::Format( wxS(
"Failed to load board: %s" ), ioe.
What() );
1036 *aError = wxS(
"Failed to load board" );
1052 wxCHECK( aServer,
false );
1057 *aError = wxS(
"No document is currently open" );
1064 wxFileName currentBoard(
m_openContext->GetCurrentFileName() );
1066 if( currentBoard.GetFullName() != aFileName )
1069 *aError = wxS(
"Requested document does not match the open document" );
1082 constexpr static int interval = 150;
1083 constexpr static int timeLimit = 120000;
1101 [
this, aKiway]() ->
void
1103 std::shared_ptr<BACKGROUND_JOB_REPORTER>
reporter =
1109 bool aborted =
false;
1111 reporter->Report(
_(
"Loading Footprint Libraries" ) );
1123 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
1127 float progress = *loadStatus;
1128 reporter->SetCurrentProgress( progress );
1139 elapsed += interval;
1141 if( elapsed > timeLimit )
1163 "pcbnew PreloadLibraries: adapter errors.IsEmpty()=%d, length=%zu",
1164 errors.IsEmpty(), errors.length() );
1166 if( !errors.IsEmpty() )
1168 std::vector<LOAD_MESSAGE> messages =
1171 wxLogTrace(
traceLibraries,
" -> adapter: collected %zu messages",
1174 if( !messages.empty() )
1179 wxLogTrace(
traceLibraries,
" -> no errors from footprint adapter" );
1184 wxLogTrace(
traceLibraries,
"pcbnew PreloadLibraries: aborted, skipping footprint processing" );
1195 std::string payload =
"";
1202 std::future<void> preloadFuture = std::async( std::launch::async, preload );
constexpr EDA_IU_SCALE pcbIUScale
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static std::list< TOOL_ACTION * > & GetActionList()
Return list of TOOL_ACTIONs.
std::shared_ptr< BACKGROUND_JOB > Create(const wxString &aName)
Creates a background job with the given name.
void Remove(std::shared_ptr< BACKGROUND_JOB > job)
Removes the given background job from any lists and frees it.
static std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
static CLI_PROGRESS_REPORTER & GetInstance()
static CLI_REPORTER & GetInstance()
The base frame for deriving all KiCad main window classes.
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()
An simple container class that lets us dispatch output jobs to kifaces.
void RegisterHandler(API_HANDLER *aHandler)
Adds a new request handler to the server.
void DeregisterHandler(API_HANDLER *aHandler)
KIFACE_BASE(const char *aKifaceName, KIWAY::FACE_T aId)
void InitSettings(APP_SETTINGS_BASE *aSettings)
void end_common()
Common things to do for a top program module, during OnKifaceEnd();.
APP_SETTINGS_BASE * KifaceSettings() const
bool start_common(int aCtlBits)
Common things to do for a top program module, during OnKifaceStart().
int m_start_flags
flags provided in OnKifaceStart()
bool IsSingle() const
Is this KIFACE running under single_top?
static int Apply(const git_merge_driver_source *aSrc, const char **aPathOut, unsigned int *aModeOut, git_buf *aMergedOut)
libgit2 merge-driver apply callback shim.
static int Apply(const git_merge_driver_source *aSrc, const char **aPathOut, unsigned int *aModeOut, git_buf *aMergedOut)
A mix in class which holds the location of a wxWindow's KIWAY.
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 void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
FACE_T
Known KIFACE implementations.
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
std::optional< float > AsyncLoadProgress() const
Returns async load progress between 0.0 and 1.0, or nullopt if load is not in progress.
void AbortAsyncLoad()
Aborts any async load in progress; blocks until fully done aborting.
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
The main frame for Pcbnew.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
Container for data for KiCad programs.
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
void ClearLibraryLoadMessages()
Clear library load messages from all registered status bars.
void AddLibraryLoadMessages(const std::vector< LOAD_MESSAGE > &aMessages)
Add library load messages to all registered status bars.
virtual SETTINGS_MANAGER & GetSettingsManager() const
A progress reporter interface for use in multi-threaded environments.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
T * RegisterSettings(T *aSettings, bool aLoadNow=true)
Take ownership of the pointer passed in.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT * GetProject(const wxString &aFullPath) const
Retrieve a loaded project by name.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
UNITS_PROVIDER(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits)
EDA_UNITS GetUserUnits() const
void SetUserUnits(EDA_UNITS aUnits)
This file is part of the common library.
#define KICAD_PCB_PORT_SERVICE_NUMBER
Pcbnew listens on this port for commands from Eeschema.
Abstract pattern-matching tool and implementations.
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
@ PANEL_FP_DEFAULT_GRAPHICS_VALUES
@ PANEL_FP_DISPLAY_OPTIONS
@ PANEL_FP_USER_LAYER_NAMES
@ DIALOG_PCB_LIBRARY_TABLE
@ FRAME_FOOTPRINT_PREVIEW
@ FRAME_FOOTPRINT_CHOOSER
@ PANEL_FP_DEFAULT_FIELDS
@ PANEL_PCB_ACTION_PLUGINS
@ PANEL_3DV_DISPLAY_OPTIONS
void CopySexprFile(const wxString &aSrcPath, const wxString &aDestPath, std::function< bool(const std::string &token, wxString &value)> aCallback, wxString &aErrors)
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string FootprintLibraryTableFileName
static const std::string BackupFileSuffix
static const std::string LegacyFootprintLibPathExtension
static const std::string FootprintAssignmentFileExtension
static const std::string KiCadFootprintFileExtension
static const std::string KiCadPcbFileExtension
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
@ KIFACE_MERGE_DOCUMENT
int (*)( int aKind, const wxString& aAncestor, const wxString& aOurs, const wxString& aTheirs,...
@ KIFACE_FOOTPRINT_LIBRARY_ADAPTER
@ KIFACE_FILTER_FOOTPRINTS
Function pointer type: wxString (*)(const wxString& aFilterJson) Input JSON: {"pin_count": N,...
@ KIFACE_OPEN_DIFF_DIALOG
int (*)( int aKind, const wxString& aFileA, const wxString& aFileB, const wxString& aLabelA,...
#define KFCTL_CLI
Running as CLI app.
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
This file contains miscellaneous commonly used macros and functions.
DOC_KIND
Document type a diff/merge entry point should route to, derived from a file path's extension.
bool RegisterMergeDriver(const char *aName, MERGE_APPLY_FN aApply)
Register a KiCad merge driver with libgit2.
PCB::IFACE KIFACE_BASE, UNITS_PROVIDER kiface("pcbnew", KIWAY::FACE_PCB)
static int pcbnewOpenDiffDialogExport(int aKind, const wxString &aFileA, const wxString &aFileB, const wxString &aLabelA, const wxString &aLabelB, wxWindow *aParent, REPORTER *aReporter)
static int pcbnewMergeExport(int aKind, const wxString &aAncestor, const wxString &aOurs, const wxString &aTheirs, const wxString &aOutput, bool aInteractive, bool aSingleFile, REPORTER *aReporter)
void InvokePcbLibTableEditor(KIWAY *aKiway, wxWindow *aCaller)
Function InvokePcbLibTableEditor shows the modal DIALOG_FP_LIB_TABLE for purposes of editing the glob...
static wxString filterFootprints(const wxString &aFilterJson)
Filter footprints based on criteria passed as JSON.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
PGM_BASE & Pgm()
The global program "get" accessor.
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
std::vector< LOAD_MESSAGE > ExtractLibraryLoadErrors(const wxString &aErrorString, int aSeverity)
Parse library load error messages, extracting user-facing information while stripping internal code l...
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
Implement a participant in the KIWAY alchemy.
std::atomic_bool m_libraryPreloadInProgress
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
void PreloadLibraries(KIWAY *aKiway) override
void ProjectChanged() override
void SaveFileAs(const wxString &aProjectBasePath, const wxString &aSrcProjectName, const wxString &aNewProjectBasePath, const wxString &aNewProjectName, const wxString &aSrcFilePath, wxString &aErrors) override
Saving a file under a different name is delegated to the various KIFACEs because the project doesn't ...
void CancelPreload(bool aBlock=true) override
void closeCurrentDocument(KICAD_API_SERVER *aServer)
std::shared_ptr< BACKGROUND_JOB > m_libraryPreloadBackgroundJob
void * IfaceOrAddress(int aDataId) override
Return a pointer to the requested object.
void Reset() override
Reloads global state.
std::unique_ptr< API_HANDLER_FOOTPRINT > m_openFpHandler
wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Create a wxWindow for the current project.
bool HandleApiOpenDocument(const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError) override
bool handleOpenFootprint(const wxString &aProjectPath, const wxString &aLibIdStr, KICAD_API_SERVER *aServer, wxString *aError)
IFACE(const char *aName, KIWAY::FACE_T aType)
std::unique_ptr< API_HANDLER_PCB > m_openHandler
std::atomic_bool m_libraryPreloadAbort
bool HandleApiCloseDocument(const wxString &aBoardFileName, KICAD_API_SERVER *aServer, wxString *aError) override
int HandleJob(JOB *aJob, REPORTER *aReporter, PROGRESS_REPORTER *aProgressReporter) override
std::shared_ptr< HEADLESS_FOOTPRINT_CONTEXT > m_openFpContext
std::shared_ptr< HEADLESS_PCB_CONTEXT > m_openContext
PCBNEW_JOBS_HANDLER * JobHandler() const
Accessor for the non-job diff/merge exports (pcbnewMergeExport etc.).
std::unique_ptr< PCBNEW_JOBS_HANDLER > m_jobHandler
bool HandleJobConfig(JOB *aJob, wxWindow *aParent) override
bool handleOpenPcb(const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError)
void OnKifaceEnd() override
Called just once just before the DSO is to be unloaded.
std::future< void > m_libraryPreloadReturn
IbisParser parser & reporter
KIBIS top(path, &reporter)
VECTOR3I expected(15, 30, 45)
static const long long MM
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.