KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_project_settings.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 (C) 2020 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <functional>
22#include <lset.h>
23#include <lseq.h>
27
28using namespace std::placeholders;
29
30
32 std::vector<LAYER_PRESET>* aPresetList ) :
33 PARAM_LAMBDA<nlohmann::json>( aPath,
34 std::bind( &PARAM_LAYER_PRESET::presetsToJson, this ),
35 std::bind( &PARAM_LAYER_PRESET::jsonToPresets, this, _1 ),
36 {} ),
37 m_presets( aPresetList )
38{
39 wxASSERT( aPresetList );
40}
41
42
44{
45 nlohmann::json ret = nlohmann::json::array();
46
47 for( const LAYER_PRESET& preset : *m_presets )
48 {
49 nlohmann::json js = {
50 { "name", preset.name },
51 { "activeLayer", preset.activeLayer },
52 { "flipBoard", preset.flipBoard }
53 };
54
55 nlohmann::json layers = nlohmann::json::array();
56
57 for( PCB_LAYER_ID layer : preset.layers.Seq() )
58 layers.push_back( static_cast<int>( layer ) );
59
60 js["layers"] = layers;
61
62 nlohmann::json renderLayers = nlohmann::json::array();
63
64 for( GAL_LAYER_ID layer : preset.renderLayers.Seq() )
65 {
66 if( std::optional<VISIBILITY_LAYER> vl = VisibilityLayerFromRenderLayer( layer ) )
67 renderLayers.push_back( VisibilityLayerToString( *vl ) );
68 }
69
70 js["renderLayers"] = renderLayers;
71
72 ret.push_back( js );
73 }
74
75 return ret;
76}
77
78
79void PARAM_LAYER_PRESET::jsonToPresets( const nlohmann::json& aJson )
80{
81 if( aJson.empty() || !aJson.is_array() )
82 return;
83
84 m_presets->clear();
85
86 for( const nlohmann::json& preset : aJson )
87 {
88 if( preset.contains( "name" ) )
89 {
90 LAYER_PRESET p( preset.at( "name" ).get<wxString>() );
91
92 if( preset.contains( "flipBoard" ) && preset.at( "flipBoard" ).is_boolean() )
93 {
94 p.flipBoard = preset.at( "flipBoard" ).get<bool>();
95 }
96
97 if( preset.contains( "activeLayer" ) && preset.at( "activeLayer" ).is_number_integer() )
98 {
99 int active = preset.at( "activeLayer" ).get<int>();
100
101 if( active >= 0 && active < PCB_LAYER_ID_COUNT )
102 p.activeLayer = static_cast<PCB_LAYER_ID>( active );
103 }
104
105 if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
106 {
107 p.layers.reset();
108
109 for( const nlohmann::json& layer : preset.at( "layers" ) )
110 {
111 if( layer.is_number_integer() )
112 {
113 int layerNum = layer.get<int>();
114
115 if( layerNum >= 0 && layerNum < PCB_LAYER_ID_COUNT )
116 p.layers.set( layerNum );
117 }
118 }
119 }
120
121 if( preset.contains( "renderLayers" ) && preset.at( "renderLayers" ).is_array() )
122 {
123 p.renderLayers.reset();
124
125 for( const nlohmann::json& layer : preset.at( "renderLayers" ) )
126 {
127 if( layer.is_string() )
128 {
129 std::string vs = layer.get<std::string>();
130
131 if( std::optional<GAL_LAYER_ID> rl = RenderLayerFromVisbilityString( vs ) )
132 p.renderLayers.set( *rl );
133 }
134 }
135 }
136
137 m_presets->emplace_back( p );
138 }
139 }
140}
141
142
143void PARAM_LAYER_PRESET::MigrateToV9Layers( nlohmann::json& aJson )
144{
145 if( !aJson.is_object() || !aJson.contains( "layers" ) )
146 return;
147
148 std::vector<int> newLayers;
149
150 for( const nlohmann::json& layer : aJson.at( "layers" ) )
151 {
152 wxCHECK2( layer.is_number_integer(), continue );
153 newLayers.emplace_back( BoardLayerFromLegacyId( layer.get<int>() ) );
154 }
155
156 aJson["layers"] = newLayers;
157
158 if( aJson.contains( "activeLayer" ) )
159 aJson["activeLayer"] = BoardLayerFromLegacyId( aJson.at( "activeLayer" ).get<int>() );
160}
161
162
164{
165 static constexpr int V8_GAL_LAYER_ID_START = 125;
166
167 if( !aJson.is_object() || !aJson.contains( "renderLayers" ) )
168 return;
169
170 std::vector<std::string> newLayers;
171
172 for( const nlohmann::json& layer : aJson.at( "renderLayers" ) )
173 {
174 wxCHECK2( layer.is_number_integer(), continue );
175 GAL_LAYER_ID layerId = GAL_LAYER_ID_START + ( layer.get<int>() - V8_GAL_LAYER_ID_START );
176
177 if( std::optional<VISIBILITY_LAYER> vl = VisibilityLayerFromRenderLayer( layerId ) )
178 newLayers.emplace_back( VisibilityLayerToString( *vl ) );
179 }
180
181 aJson["renderLayers"] = newLayers;
182}
183
184
185PARAM_VIEWPORT::PARAM_VIEWPORT( const std::string& aPath, std::vector<VIEWPORT>* aViewportList ) :
186 PARAM_LAMBDA<nlohmann::json>( aPath,
187 std::bind( &PARAM_VIEWPORT::viewportsToJson, this ),
188 std::bind( &PARAM_VIEWPORT::jsonToViewports, this, _1 ),
189 {} ),
190 m_viewports( aViewportList )
191{
192 wxASSERT( aViewportList );
193}
194
195
197{
198 nlohmann::json ret = nlohmann::json::array();
199
200 for( const VIEWPORT& viewport : *m_viewports )
201 {
202 nlohmann::json js = {
203 { "name", viewport.name },
204 { "x", viewport.rect.GetX() },
205 { "y", viewport.rect.GetY() },
206 { "w", viewport.rect.GetWidth() },
207 { "h", viewport.rect.GetHeight() }
208 };
209
210 ret.push_back( js );
211 }
212
213 return ret;
214}
215
216
217void PARAM_VIEWPORT::jsonToViewports( const nlohmann::json& aJson )
218{
219 if( aJson.empty() || !aJson.is_array() )
220 return;
221
222 m_viewports->clear();
223
224 for( const nlohmann::json& viewport : aJson )
225 {
226 if( viewport.contains( "name" ) )
227 {
228 VIEWPORT v( viewport.at( "name" ).get<wxString>() );
229
230 if( viewport.contains( "x" ) )
231 v.rect.SetX( viewport.at( "x" ).get<double>() );
232
233 if( viewport.contains( "y" ) )
234 v.rect.SetY( viewport.at( "y" ).get<double>() );
235
236 if( viewport.contains( "w" ) )
237 v.rect.SetWidth( viewport.at( "w" ).get<double>() );
238
239 if( viewport.contains( "h" ) )
240 v.rect.SetHeight( viewport.at( "h" ).get<double>() );
241
242 m_viewports->emplace_back( v );
243 }
244 }
245}
246
247
248PARAM_VIEWPORT3D::PARAM_VIEWPORT3D( const std::string& aPath,
249 std::vector<VIEWPORT3D>* aViewportList ) :
250 PARAM_LAMBDA<nlohmann::json>( aPath,
251 std::bind( &PARAM_VIEWPORT3D::viewportsToJson, this ),
252 std::bind( &PARAM_VIEWPORT3D::jsonToViewports, this, _1 ),
253 {} ),
254 m_viewports( aViewportList )
255{
256 wxASSERT( aViewportList );
257}
258
259
261{
262 nlohmann::json ret = nlohmann::json::array();
263
264 for( const VIEWPORT3D& viewport : *m_viewports )
265 {
266 nlohmann::json js = {
267 { "name", viewport.name },
268 { "xx", viewport.matrix[0].x },
269 { "xy", viewport.matrix[0].y },
270 { "xz", viewport.matrix[0].z },
271 { "xw", viewport.matrix[0].w },
272 { "yx", viewport.matrix[1].x },
273 { "yy", viewport.matrix[1].y },
274 { "yz", viewport.matrix[1].z },
275 { "yw", viewport.matrix[1].w },
276 { "zx", viewport.matrix[2].x },
277 { "zy", viewport.matrix[2].y },
278 { "zz", viewport.matrix[2].z },
279 { "zw", viewport.matrix[2].w },
280 { "wx", viewport.matrix[3].x },
281 { "wy", viewport.matrix[3].y },
282 { "wz", viewport.matrix[3].z },
283 { "ww", viewport.matrix[3].w }
284 };
285
286 ret.push_back( js );
287 }
288
289 return ret;
290}
291
292
293void PARAM_VIEWPORT3D::jsonToViewports( const nlohmann::json& aJson )
294{
295 if( aJson.empty() || !aJson.is_array() )
296 return;
297
298 m_viewports->clear();
299
300 for( const nlohmann::json& viewport : aJson )
301 {
302 if( viewport.contains( "name" ) )
303 {
304 VIEWPORT3D v( viewport.at( "name" ).get<wxString>() );
305
306 if( viewport.contains( "xx" ) )
307 v.matrix[0].x = viewport.at( "xx" ).get<double>();
308
309 if( viewport.contains( "xy" ) )
310 v.matrix[0].y = viewport.at( "xy" ).get<double>();
311
312 if( viewport.contains( "xz" ) )
313 v.matrix[0].z = viewport.at( "xz" ).get<double>();
314
315 if( viewport.contains( "xw" ) )
316 v.matrix[0].w = viewport.at( "xw" ).get<double>();
317
318 if( viewport.contains( "yx" ) )
319 v.matrix[1].x = viewport.at( "yx" ).get<double>();
320
321 if( viewport.contains( "yy" ) )
322 v.matrix[1].y = viewport.at( "yy" ).get<double>();
323
324 if( viewport.contains( "yz" ) )
325 v.matrix[1].z = viewport.at( "yz" ).get<double>();
326
327 if( viewport.contains( "yw" ) )
328 v.matrix[1].w = viewport.at( "yw" ).get<double>();
329
330 if( viewport.contains( "zx" ) )
331 v.matrix[2].x = viewport.at( "zx" ).get<double>();
332
333 if( viewport.contains( "zy" ) )
334 v.matrix[2].y = viewport.at( "zy" ).get<double>();
335
336 if( viewport.contains( "zz" ) )
337 v.matrix[2].z = viewport.at( "zz" ).get<double>();
338
339 if( viewport.contains( "zw" ) )
340 v.matrix[2].w = viewport.at( "zw" ).get<double>();
341
342 if( viewport.contains( "wx" ) )
343 v.matrix[3].x = viewport.at( "wx" ).get<double>();
344
345 if( viewport.contains( "wy" ) )
346 v.matrix[3].y = viewport.at( "wy" ).get<double>();
347
348 if( viewport.contains( "wz" ) )
349 v.matrix[3].z = viewport.at( "wz" ).get<double>();
350
351 if( viewport.contains( "ww" ) )
352 v.matrix[3].w = viewport.at( "ww" ).get<double>();
353
354 m_viewports->emplace_back( v );
355 }
356 }
357}
358
359
360PARAM_LAYER_PAIRS::PARAM_LAYER_PAIRS( const std::string& aPath,
361 std::vector<LAYER_PAIR_INFO>& aLayerPairInfos ) :
362 PARAM_LAMBDA<nlohmann::json>( aPath,
363 std::bind( &PARAM_LAYER_PAIRS::layerPairsToJson, this ),
364 std::bind( &PARAM_LAYER_PAIRS::jsonToLayerPairs, this, _1 ),
365 {} ),
366 m_layerPairInfos( aLayerPairInfos )
367{
368}
369
370
372{
373 nlohmann::json ret = nlohmann::json::array();
374
375 for( const LAYER_PAIR_INFO& pairInfo : m_layerPairInfos )
376 {
377 const LAYER_PAIR& pair = pairInfo.GetLayerPair();
378 nlohmann::json js = {
379 { "topLayer", pair.GetLayerA() },
380 { "bottomLayer", pair.GetLayerB() },
381 { "enabled", pairInfo.IsEnabled() },
382 };
383
384 if( pairInfo.GetName().has_value() )
385 {
386 js["name"] = pairInfo.GetName().value();
387 }
388
389 ret.push_back( std::move( js ) );
390 }
391
392 return ret;
393}
394
395
396void PARAM_LAYER_PAIRS::jsonToLayerPairs( const nlohmann::json& aJson )
397{
398 if( aJson.empty() || !aJson.is_array() )
399 return;
400
401 m_layerPairInfos.clear();
402
403 for( const nlohmann::json& pairJson : aJson )
404 {
405 if( pairJson.contains( "topLayer" ) && pairJson.contains( "bottomLayer" ) )
406 {
407 LAYER_PAIR pair( pairJson.at( "topLayer" ).get<PCB_LAYER_ID>(),
408 pairJson.at( "bottomLayer" ).get<PCB_LAYER_ID>() );
409
410 bool enabled = true;
411 if( pairJson.contains( "enabled" ) )
412 enabled = pairJson.at( "enabled" ).get<bool>();
413
414 std::optional<wxString> name;
415 if( pairJson.contains( "name" ) )
416 name = pairJson.at( "name" ).get<wxString>();
417
418 m_layerPairInfos.emplace_back( LAYER_PAIR_INFO( pair, enabled, std::move( name ) ) );
419 }
420 }
421}
const char * name
BASE_SET & reset(size_t pos)
Definition base_set.h:143
BASE_SET & set(size_t pos)
Definition base_set.h:116
constexpr void SetHeight(size_type val)
Definition box2.h:292
constexpr void SetWidth(size_type val)
Definition box2.h:287
constexpr void SetX(coord_type val)
Definition box2.h:277
constexpr void SetY(coord_type val)
Definition box2.h:282
GAL_SET & set()
Definition layer_ids.h:419
All information about a layer pair as stored in the layer pair store.
PCB_LAYER_ID GetLayerA() const
PCB_LAYER_ID GetLayerB() const
PARAM_LAMBDA(const std::string &aJsonPath, std::function< nlohmann::json()> aGetter, std::function< void(nlohmann::json)> aSetter, nlohmann::json aDefault, bool aReadOnly=false)
Definition parameters.h:299
nlohmann::json layerPairsToJson()
void jsonToLayerPairs(const nlohmann::json &aJson)
std::vector< LAYER_PAIR_INFO > & m_layerPairInfos
PARAM_LAYER_PAIRS(const std::string &aPath, std::vector< LAYER_PAIR_INFO > &m_layerPairInfos)
static void MigrateToV9Layers(nlohmann::json &aJson)
static void MigrateToNamedRenderLayers(nlohmann::json &aJson)
PARAM_LAYER_PRESET(const std::string &aPath, std::vector< LAYER_PRESET > *aPresetList)
std::vector< LAYER_PRESET > * m_presets
void jsonToPresets(const nlohmann::json &aJson)
void jsonToViewports(const nlohmann::json &aJson)
PARAM_VIEWPORT3D(const std::string &aPath, std::vector< VIEWPORT3D > *aViewportList)
nlohmann::json viewportsToJson()
std::vector< VIEWPORT3D > * m_viewports
std::vector< VIEWPORT > * m_viewports
PARAM_VIEWPORT(const std::string &aPath, std::vector< VIEWPORT > *aViewportList)
nlohmann::json viewportsToJson()
void jsonToViewports(const nlohmann::json &aJson)
nlohmann::json json
Definition gerbview.cpp:50
PCB_LAYER_ID BoardLayerFromLegacyId(int aLegacyId)
Retrieve a layer ID from an integer converted from a legacy (pre-V9) enum value.
Definition layer_id.cpp:218
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ GAL_LAYER_ID_START
Definition layer_ids.h:229
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ PCB_LAYER_ID_COUNT
Definition layer_ids.h:171
std::optional< VISIBILITY_LAYER > VisibilityLayerFromRenderLayer(GAL_LAYER_ID aLayerId)
std::string VisibilityLayerToString(VISIBILITY_LAYER aLayerId)
std::optional< GAL_LAYER_ID > RenderLayerFromVisbilityString(const std::string &aLayer)
STL namespace.
A saved set of layers that are visible.
GAL_SET renderLayers
Render layers (e.g. object types) that are visible.
bool flipBoard
True if the flip board is enabled.
LSET layers
Board layers that are visible.
PCB_LAYER_ID activeLayer
Optional layer to set active when this preset is loaded.