39#include <wx/snglinst.h>
58#include <nlohmann/json.hpp>
80#include <wx/tokenzr.h>
113 using json = nlohmann::json;
117 json input = json::parse( aFilterJson.ToStdString() );
119 int pinCount = input.value(
"pin_count", 0 );
120 bool zeroFilters = input.value(
"zero_filters",
true );
121 int maxResults = input.value(
"max_results", 400 );
123 std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> filterMatchers;
125 if( input.contains(
"filters" ) && input[
"filters"].is_array() )
127 for(
const auto& f : input[
"filters"] )
131 wxString pattern = wxString::FromUTF8( f.get<std::string>() );
132 auto matcher = std::make_unique<EDA_PATTERN_MATCH_WILDCARD_ANCHORED>();
133 matcher->SetPattern( pattern.Lower() );
134 filterMatchers.push_back( std::move( matcher ) );
139 bool hasFilters = ( pinCount > 0 || !filterMatchers.empty() );
141 if( zeroFilters && !hasFilters )
148 wxWindow* focus = wxWindow::FindFocus();
149 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
170 json output = json::array();
175 std::vector<FOOTPRINT*> footprints = adapter->
GetFootprints( nickname,
true );
187 if( fpPadCount != pinCount )
192 if( !filterMatchers.empty() )
194 bool matches =
false;
196 for(
const auto& matcher : filterMatchers )
201 if( matcher->GetPattern().Contains( wxS(
":" ) ) )
202 name = fp->GetFPID().GetLibNickname().wx_str().Lower() + wxS(
":" );
204 name += fp->GetFPID().GetLibItemName().wx_str().Lower();
206 if( matcher->Find(
name ) )
217 wxString libId = fp->GetFPID().Format();
218 output.push_back( libId.ToStdString() );
220 if( ++count >= maxResults )
224 if( count >= maxResults )
228 return wxString::FromUTF8( output.dump() );
230 catch(
const std::exception& )
241static int pcbnewMergeExport(
int aKind,
const wxString& aAncestor,
const wxString& aOurs,
242 const wxString& aTheirs,
const wxString& aOutput,
bool aInteractive,
243 bool aSingleFile, REPORTER* aReporter );
245 const wxString& aLabelA,
const wxString& aLabelB,
246 wxWindow* aParent,
REPORTER* aReporter );
260 void Reset()
override;
303 dlg.SetKiway( &dlg, aKiway );
306 if( dlg.ShowQuasiModal() == wxID_OK )
392 return new PANEL_FP_EDITOR_GRAPHICS_DEFAULTS( aParent,
this );
403 std::vector<TOOL_ACTION*> actions;
404 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
407 actions.push_back( action );
410 controls.push_back( control );
416 return new PANEL_FP_EDITOR_COLOR_SETTINGS( aParent );
435 return new PANEL_GRID_SETTINGS( aParent,
this, frame, cfg,
FRAME_PCB_EDITOR );
459 return new PANEL_EDIT_OPTIONS( aParent,
this, frame,
false );
464 BOARD* board =
nullptr;
468 board =
static_cast<PCB_EDIT_FRAME*
>( boardProvider )->GetBoard();
470 return new PANEL_PCBNEW_COLOR_SETTINGS( aParent, board );
478 std::vector<TOOL_ACTION*> actions;
479 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
482 actions.push_back( action );
485 controls.push_back( control );
487 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_EDITOR, actions, controls );
491 return new PANEL_PCBNEW_ACTION_PLUGINS( aParent );
494 return new PANEL_3D_DISPLAY_OPTIONS( aParent );
497 return new PANEL_3D_OPENGL_OPTIONS( aParent );
500 return new PANEL_3D_RAYTRACING_OPTIONS( aParent );
507 std::vector<TOOL_ACTION*> actions;
508 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
511 actions.push_back( action );
514 controls.push_back( control );
516 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_DISPLAY3D, actions, controls );
546 wxWindow* focus = wxWindow::FindFocus();
547 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
588 void SaveFileAs(
const wxString& aProjectBasePath,
const wxString& aSrcProjectName,
589 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
590 const wxString& aSrcFilePath, wxString& aErrors )
override;
598 wxString* aError )
override;
602 wxString* aError )
override;
632 const wxString& aTheirs,
const wxString& aOutput,
bool aInteractive,
633 bool aSingleFile,
REPORTER* aReporter )
636 aOurs, aTheirs, aOutput, aInteractive, aSingleFile,
642 const wxString& aLabelA,
const wxString& aLabelB,
643 wxWindow* aParent,
REPORTER* aReporter )
646 aFileB, aLabelA, aLabelB, aParent, aReporter );
691 m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>( aKiway );
728 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
729 const wxString& aSrcFilePath, wxString& aErrors )
731 wxFileName destFile( aSrcFilePath );
732 wxString destPath = destFile.GetPathWithSep();
733 wxUniChar pathSep = wxFileName::GetPathSeparator();
734 wxString ext = destFile.GetExt();
736 if( destPath.StartsWith( aProjectBasePath + pathSep ) )
737 destPath.Replace( aProjectBasePath, aNewProjectBasePath,
false );
739 wxString srcProjectFootprintLib = pathSep + aSrcProjectName + wxT(
".pretty" ) + pathSep;
740 wxString newProjectFootprintLib = pathSep + aNewProjectName + wxT(
".pretty" ) + pathSep;
742 destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib,
true );
744 destFile.SetPath( destPath );
749 if( destFile.GetName() == aSrcProjectName )
750 destFile.SetName( aNewProjectName );
753 [&](
const std::string& token, wxString& value )
755 if( token ==
"sheetfile" )
757 for( const wxString extension : { wxT(
".sch" ), wxT(
".kicad_sch" ) } )
759 if( value == aSrcProjectName + extension )
761 value = aNewProjectName + extension;
764 else if( value == aProjectBasePath +
"/" + aSrcProjectName + extension )
766 value = aNewProjectBasePath +
"/" + aNewProjectName + extension;
769 else if( value.StartsWith( aProjectBasePath ) )
771 value.Replace( aProjectBasePath, aNewProjectBasePath, false );
783 if( destFile.GetName() == aSrcProjectName )
784 destFile.SetName( aNewProjectName );
786 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
792 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
798 else if( ext == wxT(
"rpt" ) )
804 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
808 wxFileName libTableFn( aSrcFilePath );
810 libTable.SetPath( destFile.GetFullPath() );
813 for( LIBRARY_TABLE_ROW& row : libTable.Rows() )
815 wxString uri = row.URI();
817 uri.Replace( wxT(
"/" ) + aSrcProjectName + wxT(
".pretty" ),
818 wxT(
"/" ) + aNewProjectName + wxT(
".pretty" ) );
823 libTable.Save().map_error(
824 [&](
const LIBRARY_ERROR& aError )
828 if( !aErrors.empty() )
829 aErrors += wxT(
"\n" );
831 msg.Printf(
_(
"Cannot copy file '%s'." ), destFile.GetFullPath() );
837 wxFAIL_MSG( wxT(
"Unexpected filetype for Pcbnew::SaveFileAs()" ) );
844 return m_jobHandler->RunJob( aJob, aReporter, aProgressReporter );
884 wxCHECK( aServer,
false );
886 if( aPath.IsEmpty() )
889 *aError = wxS(
"No path specified to open" );
903 if( fpid.
Parse( aLibIdStr ) >= 0 )
906 *aError = wxString::Format( wxS(
"Invalid footprint LIB_ID: %s" ), aLibIdStr );
911 wxFileName projectPath( aProjectPath );
912 projectPath.MakeAbsolute();
916 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
918 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aProjectPath );
926 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aProjectPath );
931 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> newContext;
943 *aError = wxString::Format( wxS(
"Footprint not found: %s" ), aLibIdStr );
948 newContext = std::make_shared<HEADLESS_FOOTPRINT_CONTEXT>(
954 *aError = wxString::Format( wxS(
"Failed to load footprint: %s" ), aLibIdStr );
971 wxFileName projectPath( aPath );
978 projectPath.MakeAbsolute();
987 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
989 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aPath );
997 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aPath );
1002 wxFileName boardPath( projectPath );
1005 if( !boardPath.FileExists() )
1008 *aError = wxString::Format( wxS(
"File not found: %s" ), aPath );
1019 *aError = wxString::Format( wxS(
"%s is not a recognized file type" ), aPath );
1024 std::shared_ptr<HEADLESS_PCB_CONTEXT> newContext;
1033 *aError = wxS(
"Failed to load board" );
1038 newContext = std::make_shared<HEADLESS_PCB_CONTEXT>( std::move( loadedBoard ),
project,
1044 *aError = wxString::Format( wxS(
"Failed to load board: %s" ), ioe.
What() );
1051 *aError = wxS(
"Failed to load board" );
1067 wxCHECK( aServer,
false );
1072 *aError = wxS(
"No document is currently open" );
1079 wxFileName currentBoard(
m_openContext->GetCurrentFileName() );
1081 if( currentBoard.GetFullName() != aFileName )
1084 *aError = wxS(
"Requested document does not match the open document" );
1097 constexpr static int interval = 150;
1098 constexpr static int timeLimit = 120000;
1116 [
this, aKiway]() ->
void
1118 std::shared_ptr<BACKGROUND_JOB_REPORTER>
reporter =
1124 bool aborted =
false;
1126 reporter->Report(
_(
"Loading Footprint Libraries" ) );
1138 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
1142 float progress = *loadStatus;
1143 reporter->SetCurrentProgress( progress );
1154 elapsed += interval;
1156 if( elapsed > timeLimit )
1178 "pcbnew PreloadLibraries: adapter errors.IsEmpty()=%d, length=%zu",
1179 errors.IsEmpty(), errors.length() );
1181 if( !errors.IsEmpty() )
1183 std::vector<LOAD_MESSAGE> messages =
1186 wxLogTrace(
traceLibraries,
" -> adapter: collected %zu messages",
1189 if( !messages.empty() )
1194 wxLogTrace(
traceLibraries,
" -> no errors from footprint adapter" );
1199 wxLogTrace(
traceLibraries,
"pcbnew PreloadLibraries: aborted, skipping footprint processing" );
1210 std::string payload =
"";
1217 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.
MAGNETIC_SETTINGS m_MagneticItems
SNAP_INFERENCE_SETTINGS m_SnapInference
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...
PANEL_SNAPPING * CreateSnappingPanel(wxWindow *aParent, SETTINGS_T *aCfg, FRAME_T aFrameType, SNAP_INFERENCE_SETTINGS SETTINGS_T::*aInference=nullptr, MAGNETIC_SETTINGS SETTINGS_T::*aMagnetics=nullptr)
Build the snapping page for an editor.
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.