37#include <wx/snglinst.h>
53#include <nlohmann/json.hpp>
74#include <wx/tokenzr.h>
87#if defined( KICAD_IPC_API )
116 using json = nlohmann::json;
120 json input = json::parse( aFilterJson.ToStdString() );
122 int pinCount = input.value(
"pin_count", 0 );
123 bool zeroFilters = input.value(
"zero_filters",
true );
124 int maxResults = input.value(
"max_results", 400 );
126 std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> filterMatchers;
128 if( input.contains(
"filters" ) && input[
"filters"].is_array() )
130 for(
const auto& f : input[
"filters"] )
134 wxString pattern = wxString::FromUTF8( f.get<std::string>() );
135 auto matcher = std::make_unique<EDA_PATTERN_MATCH_WILDCARD_ANCHORED>();
136 matcher->SetPattern( pattern.Lower() );
137 filterMatchers.push_back( std::move( matcher ) );
142 bool hasFilters = ( pinCount > 0 || !filterMatchers.empty() );
144 if( zeroFilters && !hasFilters )
151 wxWindow* focus = wxWindow::FindFocus();
152 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
178 std::vector<FOOTPRINT*> footprints = adapter->
GetFootprints( nickname,
true );
190 if( fpPadCount != pinCount )
195 if( !filterMatchers.empty() )
197 bool matches =
false;
199 for(
const auto& matcher : filterMatchers )
204 if( matcher->GetPattern().Contains( wxS(
":" ) ) )
205 name = fp->GetFPID().GetLibNickname().wx_str().Lower() + wxS(
":" );
207 name += fp->GetFPID().GetLibItemName().wx_str().Lower();
209 if( matcher->Find(
name ) )
220 wxString libId = fp->GetFPID().Format();
221 output.push_back( libId.ToStdString() );
223 if( ++count >= maxResults )
227 if( count >= maxResults )
231 return wxString::FromUTF8(
output.dump() );
233 catch(
const std::exception& )
253 void Reset()
override;
296 dlg.SetKiway( &dlg, aKiway );
299 if( dlg.ShowQuasiModal() == wxID_OK )
380 return new PANEL_FP_EDITOR_GRAPHICS_DEFAULTS( aParent,
this );
391 std::vector<TOOL_ACTION*> actions;
392 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
395 actions.push_back( action );
398 controls.push_back( control );
404 return new PANEL_FP_EDITOR_COLOR_SETTINGS( aParent );
423 return new PANEL_GRID_SETTINGS( aParent,
this, frame, cfg,
FRAME_PCB_EDITOR );
443 return new PANEL_EDIT_OPTIONS( aParent,
this, frame,
false );
448 BOARD* board =
nullptr;
452 board =
static_cast<PCB_EDIT_FRAME*
>( boardProvider )->GetBoard();
454 return new PANEL_PCBNEW_COLOR_SETTINGS( aParent, board );
462 std::vector<TOOL_ACTION*> actions;
463 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
466 actions.push_back( action );
469 controls.push_back( control );
471 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_EDITOR, actions, controls );
475 return new PANEL_PCBNEW_ACTION_PLUGINS( aParent );
478 return new PANEL_3D_DISPLAY_OPTIONS( aParent );
481 return new PANEL_3D_OPENGL_OPTIONS( aParent );
484 return new PANEL_3D_RAYTRACING_OPTIONS( aParent );
491 std::vector<TOOL_ACTION*> actions;
492 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
495 actions.push_back( action );
498 controls.push_back( control );
500 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb,
FRAME_PCB_DISPLAY3D, actions, controls );
530 wxWindow* focus = wxWindow::FindFocus();
531 wxWindow*
top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
563 void SaveFileAs(
const wxString& aProjectBasePath,
const wxString& aSrcProjectName,
564 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
565 const wxString& aSrcFilePath, wxString& aErrors )
override;
571#if defined( KICAD_IPC_API )
574 wxString* aError )
override;
578 wxString* aError )
override;
580 bool handleOpenPcb(
const wxString& aPath,
KICAD_API_SERVER* aServer, wxString* aError );
582 bool handleOpenFootprint(
const wxString& aProjectPath,
const wxString& aLibIdStr,
KICAD_API_SERVER* aServer,
597#if defined( KICAD_IPC_API )
600 KIWAY* m_kiway =
nullptr;
601 std::shared_ptr<HEADLESS_PCB_CONTEXT> m_openContext;
602 std::unique_ptr<API_HANDLER_PCB> m_openHandler;
603 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> m_openFpContext;
604 std::unique_ptr<API_HANDLER_FOOTPRINT> m_openFpHandler;
649#if defined( KICAD_IPC_API )
653 m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>( aKiway );
677 const wxString& aNewProjectBasePath,
const wxString& aNewProjectName,
678 const wxString& aSrcFilePath, wxString& aErrors )
680 wxFileName destFile( aSrcFilePath );
681 wxString destPath = destFile.GetPathWithSep();
682 wxUniChar pathSep = wxFileName::GetPathSeparator();
683 wxString ext = destFile.GetExt();
685 if( destPath.StartsWith( aProjectBasePath + pathSep ) )
686 destPath.Replace( aProjectBasePath, aNewProjectBasePath,
false );
688 wxString srcProjectFootprintLib = pathSep + aSrcProjectName + wxT(
".pretty" ) + pathSep;
689 wxString newProjectFootprintLib = pathSep + aNewProjectName + wxT(
".pretty" ) + pathSep;
691 destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib,
true );
693 destFile.SetPath( destPath );
698 if( destFile.GetName() == aSrcProjectName )
699 destFile.SetName( aNewProjectName );
702 [&](
const std::string& token, wxString& value )
704 if( token ==
"sheetfile" )
706 for( const wxString extension : { wxT(
".sch" ), wxT(
".kicad_sch" ) } )
708 if( value == aSrcProjectName + extension )
710 value = aNewProjectName + extension;
713 else if( value == aProjectBasePath +
"/" + aSrcProjectName + extension )
715 value = aNewProjectBasePath +
"/" + aNewProjectName + extension;
718 else if( value.StartsWith( aProjectBasePath ) )
720 value.Replace( aProjectBasePath, aNewProjectBasePath, false );
732 if( destFile.GetName() == aSrcProjectName )
733 destFile.SetName( aNewProjectName );
735 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
741 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
747 else if( ext == wxT(
"rpt" ) )
753 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
757 wxFileName libTableFn( aSrcFilePath );
759 libTable.SetPath( destFile.GetFullPath() );
762 for( LIBRARY_TABLE_ROW& row : libTable.Rows() )
764 wxString uri = row.URI();
766 uri.Replace( wxT(
"/" ) + aSrcProjectName + wxT(
".pretty" ),
767 wxT(
"/" ) + aNewProjectName + wxT(
".pretty" ) );
772 libTable.Save().map_error(
773 [&](
const LIBRARY_ERROR& aError )
777 if( !aErrors.empty() )
778 aErrors += wxT(
"\n" );
780 msg.Printf(
_(
"Cannot copy file '%s'." ), destFile.GetFullPath() );
786 wxFAIL_MSG( wxT(
"Unexpected filetype for Pcbnew::SaveFileAs()" ) );
793 return m_jobHandler->RunJob( aJob, aReporter, aProgressReporter );
803#if defined( KICAD_IPC_API )
811 m_openHandler.reset();
814 m_openContext.reset();
820 if( m_openFpHandler )
825 m_openFpHandler.reset();
828 m_openFpContext.reset();
834 wxCHECK( aServer,
false );
836 if( aPath.IsEmpty() )
839 *aError = wxS(
"No path specified to open" );
844 return handleOpenPcb( aPath, aServer, aError );
848bool IFACE::handleOpenFootprint(
const wxString& aProjectPath,
const wxString& aLibIdStr, KICAD_API_SERVER* aServer,
853 if( fpid.
Parse( aLibIdStr ) >= 0 )
856 *aError = wxString::Format( wxS(
"Invalid footprint LIB_ID: %s" ), aLibIdStr );
861 wxFileName projectPath( aProjectPath );
862 projectPath.MakeAbsolute();
866 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
868 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aProjectPath );
876 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aProjectPath );
881 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> newContext;
893 *aError = wxString::Format( wxS(
"Footprint not found: %s" ), aLibIdStr );
898 newContext = std::make_shared<HEADLESS_FOOTPRINT_CONTEXT>(
904 *aError = wxString::Format( wxS(
"Failed to load footprint: %s" ), aLibIdStr );
909 closeCurrentDocument( aServer );
910 m_openFpContext = std::move( newContext );
912 m_openFpHandler = std::make_unique<API_HANDLER_FOOTPRINT>( m_openFpContext,
nullptr );
919bool IFACE::handleOpenPcb(
const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError )
921 wxFileName projectPath( aPath );
928 projectPath.MakeAbsolute();
933 closeCurrentDocument( aServer );
937 if( !settingsManager.
LoadProject( projectPath.GetFullPath(),
true ) )
939 wxLogTrace(
traceApi,
"Warning: no project file found for %s", aPath );
947 *aError = wxString::Format( wxS(
"Error loading project for %s" ), aPath );
952 wxFileName boardPath( projectPath );
955 if( !boardPath.FileExists() )
958 *aError = wxString::Format( wxS(
"File not found: %s" ), aPath );
969 *aError = wxString::Format( wxS(
"%s is not a recognized file type" ), aPath );
974 std::shared_ptr<HEADLESS_PCB_CONTEXT> newContext;
983 *aError = wxS(
"Failed to load board" );
988 newContext = std::make_shared<HEADLESS_PCB_CONTEXT>( std::move( loadedBoard ),
project,
994 *aError = wxS(
"Failed to load board" );
999 m_openContext = std::move( newContext );
1001 m_openHandler = std::make_unique<API_HANDLER_PCB>( m_openContext,
nullptr );
1010 wxCHECK( aServer,
false );
1012 if( !m_openContext && !m_openFpContext )
1015 *aError = wxS(
"No document is currently open" );
1020 if( !aFileName.IsEmpty() && m_openContext )
1022 wxFileName currentBoard( m_openContext->GetCurrentFileName() );
1024 if( currentBoard.GetFullName() != aFileName )
1027 *aError = wxS(
"Requested document does not match the open document" );
1033 closeCurrentDocument( aServer );
1041 constexpr static int interval = 150;
1042 constexpr static int timeLimit = 120000;
1060 [
this, aKiway]() ->
void
1062 std::shared_ptr<BACKGROUND_JOB_REPORTER>
reporter =
1068 bool aborted =
false;
1070 reporter->Report(
_(
"Loading Footprint Libraries" ) );
1081 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
1085 float progress = *loadStatus;
1086 reporter->SetCurrentProgress( progress );
1097 elapsed += interval;
1099 if( elapsed > timeLimit )
1118 "pcbnew PreloadLibraries: adapter errors.IsEmpty()=%d, length=%zu",
1119 errors.IsEmpty(), errors.length() );
1121 if( !errors.IsEmpty() )
1123 std::vector<LOAD_MESSAGE> messages =
1126 wxLogTrace(
traceLibraries,
" -> adapter: collected %zu messages",
1129 if( !messages.empty() )
1134 wxLogTrace(
traceLibraries,
" -> no errors from footprint adapter" );
1139 wxLogTrace(
traceLibraries,
"pcbnew PreloadLibraries: aborted, skipping footprint processing" );
1150 std::string payload =
"";
1157 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.
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?
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.
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.
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.
std::unique_ptr< EESCHEMA_JOBS_HANDLER > m_jobHandler
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_FOOTPRINT_LIBRARY_ADAPTER
@ KIFACE_FILTER_FOOTPRINTS
Function pointer type: wxString (*)(const wxString& aFilterJson) Input JSON: {"pin_count": N,...
#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.
PCB::IFACE KIFACE_BASE, UNITS_PROVIDER kiface("pcbnew", KIWAY::FACE_PCB)
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.
virtual bool HandleApiCloseDocument(const wxString &aBoardFileName, KICAD_API_SERVER *aServer, wxString *aError)
virtual bool HandleApiOpenDocument(const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError)
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
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.
wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Create a wxWindow for the current project.
IFACE(const char *aName, KIWAY::FACE_T aType)
std::atomic_bool m_libraryPreloadAbort
int HandleJob(JOB *aJob, REPORTER *aReporter, PROGRESS_REPORTER *aProgressReporter) override
std::unique_ptr< PCBNEW_JOBS_HANDLER > m_jobHandler
bool HandleJobConfig(JOB *aJob, wxWindow *aParent) override
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.