KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_library_query.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <exception>
23
24#include <kiface_ids.h>
25#include <kiway.h>
26#include <json_common.h>
27
28
30{
31 using json = nlohmann::json;
32
34 result.m_Success = false;
35
36 try
37 {
38 const json responseJson = json::parse( aJson.utf8_string() );
39
40 if( !responseJson.is_object() )
41 return result;
42
43 result.m_Success = responseJson.value( "success", false );
44
45 if( !result.m_Success || !responseJson.contains( "matches" ) || !responseJson["matches"].is_array() )
46 {
47 result.m_Success = false;
48 return result;
49 }
50
51 const json& matches = responseJson["matches"];
52
53 result.m_Matches.reserve( matches.size() );
54
55 for( const json& match : matches )
56 {
57 if( !match.is_object() )
58 continue;
59
61
62 if( match.contains( "symbol" ) && match["symbol"].is_string() )
63 entry.m_Symbol.Parse( wxString::FromUTF8( match["symbol"].get<std::string>() ) );
64
65 entry.m_PinCount = match.value( "pins", 0 );
66 entry.m_IsDerived = match.value( "derived", false );
67
68 if( match.contains( "filter" ) && match["filter"].is_string() )
69 entry.m_MatchedFilter = wxString::FromUTF8( match["filter"].get<std::string>() );
70
71 entry.m_MatchesFootprintField = match.value( "footprint_field", false );
72
73 if( match.contains( "pin_maps" ) && match["pin_maps"].is_array() )
74 {
75 for( const json& mapName : match["pin_maps"] )
76 {
77 if( mapName.is_string() )
78 {
79 entry.m_MatchedPinMaps.push_back( wxString::FromUTF8( mapName.get<std::string>() ) );
80 }
81 }
82 }
83
84 result.m_Matches.push_back( std::move( entry ) );
85 }
86
87 result.m_IsLimited = responseJson.value( "limited", false );
88 }
89 catch( const std::exception& )
90 {
91 result.m_Matches.clear();
92 result.m_Success = false;
93 }
94
95 return result;
96}
97
98
100{
101 using json = nlohmann::json;
102
103 json output = json::object();
104 output["matches"] = json::array();
105 output["limited"] = m_IsLimited;
106 output["success"] = m_Success;
107
108 for( const FOOTPRINT_USER_MATCH& match : m_Matches )
109 {
110 json entry = json::object();
111 entry["symbol"] = match.m_Symbol.GetUniStringLibId().utf8_string();
112 entry["pins"] = match.m_PinCount;
113 entry["derived"] = match.m_IsDerived;
114
115 if( !match.m_MatchedFilter.IsEmpty() )
116 entry["filter"] = match.m_MatchedFilter.utf8_string();
117
118 entry["footprint_field"] = match.m_MatchesFootprintField;
119
120 if( !match.m_MatchedPinMaps.empty() )
121 {
122 json pinMaps = json::array();
123
124 for( const wxString& mapName : match.m_MatchedPinMaps )
125 pinMaps.push_back( mapName.utf8_string() );
126
127 entry["pin_maps"] = std::move( pinMaps );
128 }
129
130 output["matches"].push_back( std::move( entry ) );
131 }
132
133 return wxString::FromUTF8( output.dump() );
134}
135
136
138{
139 using json = nlohmann::json;
140
142
143 try
144 {
145 const json requestJson = json::parse( aJson.utf8_string() );
146
147 if( !requestJson.is_object() )
148 return query;
149
150 if( requestJson.contains( "footprint" ) && requestJson["footprint"].is_string() )
151 query.m_Footprint.Parse( wxString::FromUTF8( requestJson["footprint"].get<std::string>() ) );
152
153 query.m_MatchFilters = requestJson.value( "match_filters", query.m_MatchFilters );
154 query.m_MatchFootprintField = requestJson.value( "match_footprint_field", query.m_MatchFootprintField );
155 query.m_MatchPinMaps = requestJson.value( "match_pin_maps", query.m_MatchPinMaps );
156 query.m_MaxResults = requestJson.value( "max_results", query.m_MaxResults );
157 }
158 catch( const std::exception& )
159 {
160 query = FOOTPRINT_USERS_QUERY();
161 }
162
163 return query;
164}
165
166
168{
169 using json = nlohmann::json;
170
171 json request = json::object();
172 request["footprint"] = m_Footprint.GetUniStringLibId().utf8_string();
173 request["match_filters"] = m_MatchFilters;
174 request["match_footprint_field"] = m_MatchFootprintField;
175 request["match_pin_maps"] = m_MatchPinMaps;
176 request["max_results"] = m_MaxResults;
177
178 return wxString::FromUTF8( request.dump() );
179}
180
181
183{
184 const auto returnFailure = []() -> FOOTPRINT_USERS_RESULT
185 {
187 result.m_Success = false;
188 return result;
189 };
190
191 // Loading or reaching the eeschema kiface, and the JSON round-trip itself, can all fail.
192 try
193 {
194 KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_SCH );
195
196 if( !kiface )
197 return returnFailure();
198
199 void* address = kiface->IfaceOrAddress( KIFACE_FILTER_FOOTPRINT_USERS );
200
201 if( !address )
202 return returnFailure();
203
204 using FILTER_FUNC = wxString ( * )( const wxString& );
205 FILTER_FUNC filterUsers = reinterpret_cast<FILTER_FUNC>( address );
206
207 wxString response = filterUsers( aQuery.ToJsonStr() );
208
209 return FOOTPRINT_USERS_RESULT::FromJsonStr( response );
210 }
211 catch( const std::exception& )
212 {
213 return returnFailure();
214 }
215
216 return returnFailure();
217}
218
219
221{
222 // The implementation here is very similar to the footprint users query mechanism.
223 // Cf. StartFootprintLibrariesLoad()
224
225 try
226 {
227 KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_SCH );
228
229 if( !kiface )
230 return false;
231
232 void* address = kiface->IfaceOrAddress( KIFACE_TRIGGER_SYMBOLS_LOAD );
233
234 if( !address )
235 return false;
236
237 using LOAD_FUNC = bool ( * )();
238 LOAD_FUNC startLoad = reinterpret_cast<LOAD_FUNC>( address );
239
240 return startLoad();
241 }
242 catch( const std::exception& )
243 {
244 return false;
245 }
246
247 return false;
248}
249
250
252{
253 try
254 {
255 KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_SCH );
256
257 if( !kiface )
258 return 1.0f;
259
260 void* address = kiface->IfaceOrAddress( KIFACE_SYMBOLS_LOAD_PROGRESS );
261
262 if( !address )
263 return 1.0f;
264
265 using PROGRESS_FUNC = float ( * )();
266 PROGRESS_FUNC getProgress = reinterpret_cast<PROGRESS_FUNC>( address );
267
268 return getProgress();
269 }
270 catch( const std::exception& )
271 {
272 return 1.0f;
273 }
274}
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:348
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition kiway.cpp:207
@ FACE_SCH
eeschema DSO
Definition kiway.h:355
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
nlohmann::json json
Definition gerbview.cpp:50
@ KIFACE_FILTER_FOOTPRINT_USERS
Function pointer type: wxString (*)(const wxString& aQueryJson) Input JSON: the object written by FOO...
Definition kiface_ids.h:50
@ KIFACE_TRIGGER_SYMBOLS_LOAD
Function pointer type: bool (*)() Starts loading the symbol libraries in the background.
Definition kiface_ids.h:55
@ KIFACE_SYMBOLS_LOAD_PROGRESS
Function pointer type: float (*)() Returns how far the library loader has gotten as a fraction of the...
Definition kiface_ids.h:60
All the information needed to query the symbol libraries for the symbols using a footprint.
wxString ToJsonStr() const
Serialise to the JSON object that carries a query over the Eeschema kiface.
static FOOTPRINT_USERS_QUERY FromJsonStr(const wxString &aJson)
Parse the JSON object written by ToJsonStr().
bool m_MatchPinMaps
When true, symbols whose pin maps are bound to the footprint are returned.
int m_MaxResults
Limits the number of returned symbols; zero means no limit.
bool m_MatchFilters
When true, symbols whose footprint filters select the footprint are returned.
bool m_MatchFootprintField
When true, symbols whose footprint field names the footprint are returned.
LIB_ID m_Footprint
The footprint to find the users of.
The outcome of a footprint users query, and the JSON encoding used to move it across the Eeschema kif...
bool m_IsLimited
True if the result set is limited by the maximum number of results.
std::vector< FOOTPRINT_USER_MATCH > m_Matches
The matching symbols, in the order the libraries were searched.
static FOOTPRINT_USERS_RESULT FromJsonStr(const wxString &aJson)
Parse the JSON object written by ToJsonStr().
wxString ToJsonStr() const
Serialise to the JSON object that carries a result over the Eeschema kiface.
bool m_Success
False if the query could not be performed, in which case Matches is empty.
One symbol that uses a footprint, and the reason it matched.
wxString m_MatchedFilter
The footprint filter that selected the footprint, empty when the match did not come from a filter.
int m_PinCount
The number of pins of the matching symbol.
bool m_MatchesFootprintField
True when the symbol's footprint field names the footprint.
LIB_ID m_Symbol
The "library:symbol" name of the matching symbol.
bool m_IsDerived
True when the symbol is derived from another symbol rather than being a root symbol.
std::vector< wxString > m_MatchedPinMaps
The names of the symbol's pin maps that are bound to the footprint, in the order they were found; emp...
Implement a participant in the KIWAY alchemy.
Definition kiway.h:153
FOOTPRINT_USERS_RESULT QueryFootprintUsers(KIWAY &aKiway, const FOOTPRINT_USERS_QUERY &aQuery)
Ask the symbol libraries, for the symbols that use a given footprint (over the Eeschema kiface).
bool StartSymbolLibrariesLoad(KIWAY &aKiway)
Start loading the symbol libraries in the background.
float GetSymbolLibrariesLoadProgress(KIWAY &aKiway)
Return how far the background load of the symbol libraries has got.
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
wxString result
Test unit parsing edge cases and error handling.