DbLib: Allow inheriting field properties from source symbol

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12856
This commit is contained in:
Jon Evans 2022-11-09 21:24:31 -05:00
parent dbd498f451
commit d9d3ccd6eb
5 changed files with 88 additions and 41 deletions

View File

@ -78,29 +78,18 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
{
const nlohmann::json& pj = entry["properties"];
if( pj.contains( "description" ) )
table.properties.description = pj["description"].get<std::string>();
table.properties.description = fetchOrDefault<std::string>( pj, "description" );
if( pj.contains( "footprint_filters" ) )
{
table.properties.footprint_filters =
pj["footprint_filters"].get<std::string>();
}
table.properties.footprint_filters =
fetchOrDefault<std::string>( pj, "footprint_filters" );
if( pj.contains( "keywords" ) )
table.properties.keywords = pj["keywords"].get<std::string>();
table.properties.keywords = fetchOrDefault<std::string>( pj, "keywords" );
if( pj.contains( "exclude_from_bom" ) )
{
table.properties.exclude_from_bom =
pj["exclude_from_bom"].get<std::string>();
}
table.properties.exclude_from_bom =
fetchOrDefault<std::string>( pj, "exclude_from_bom" );
if( pj.contains( "exclude_from_board" ) )
{
table.properties.exclude_from_board =
pj["exclude_from_board"].get<std::string>();
}
table.properties.exclude_from_board =
fetchOrDefault<std::string>( pj, "exclude_from_board" );
}
if( entry.contains( "fields" ) && entry["fields"].is_array() )
@ -110,26 +99,19 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
if( fieldJson.empty() || !fieldJson.is_object() )
continue;
std::string column = fieldJson.contains( "column" )
? fieldJson["column"].get<std::string>() : "";
std::string name = fieldJson.contains( "name" )
? fieldJson["name"].get<std::string>() : "";
bool visible_on_add = !fieldJson.contains( "visible_on_add" )
|| fieldJson["visible_on_add"].get<bool>();
std::string column = fetchOrDefault<std::string>( fieldJson, "column" );
std::string name = fetchOrDefault<std::string>( fieldJson, "name" );
bool visible_on_add = fetchOrDefault<bool>( fieldJson, "visible_on_add" );
bool visible_in_chooser =
!fieldJson.contains( "visible_in_chooser" )
|| fieldJson["visible_in_chooser"].get<bool>();
bool show_name = fieldJson.contains( "show_name" )
&& fieldJson["show_name"].get<bool>();
fetchOrDefault<bool>( fieldJson, "visible_in_chooser" );
bool show_name = fetchOrDefault<bool>( fieldJson, "show_name" );
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
table.fields.emplace_back(
DATABASE_FIELD_MAPPING(
{
column, name, visible_on_add, visible_in_chooser, show_name
column, name, visible_on_add, visible_in_chooser, show_name,
inherit
} ) );
}
}

View File

@ -836,3 +836,29 @@ void from_json( const nlohmann::json& aJson, wxString& aString )
{
aString = wxString( aJson.get<std::string>().c_str(), wxConvUTF8 );
}
template<typename ResultType>
ResultType JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, const std::string& aKey,
ResultType aDefault )
{
ResultType ret = aDefault;
try
{
if( aJson.contains( aKey ) )
ret = aJson.at( aKey ).get<ResultType>();
}
catch( ... )
{
}
return ret;
}
template std::string JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson,
const std::string& aKey, std::string aDefault );
template bool JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, const std::string& aKey,
bool aDefault );

View File

@ -19,6 +19,7 @@
*/
#include <iostream>
#include <unordered_set>
#include <boost/algorithm/string.hpp>
@ -349,6 +350,14 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
symbol->SetIncludeInBom( !exclude );
}
std::vector<LIB_FIELD*> fields;
symbol->GetFields( fields );
std::unordered_map<wxString, LIB_FIELD*> fieldsMap;
for( LIB_FIELD* field : fields )
fieldsMap[field->GetName()] = field;
for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
{
if( !aRow.count( mapping.column ) )
@ -382,14 +391,32 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
continue;
}
LIB_FIELD* field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
field->SetName( mapping.name );
field->SetText( value );
field->SetVisible( mapping.visible_on_add );
field->SetAutoAdded( true );
field->SetNameShown( mapping.show_name );
LIB_FIELD* field;
bool isNew = false;
symbol->AddField( field );
if( fieldsMap.count( mapping.name ) )
{
field = fieldsMap[mapping.name];
}
else
{
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
field->SetName( mapping.name );
isNew = true;
fieldsMap[mapping.name] = field;
}
if( !mapping.inherit_properties || isNew )
{
field->SetVisible( mapping.visible_on_add );
field->SetAutoAdded( true );
field->SetNameShown( mapping.show_name );
}
field->SetText( value );
if( isNew )
symbol->AddField( field );
m_customFields.insert( mapping.name );

View File

@ -49,6 +49,7 @@ struct DATABASE_FIELD_MAPPING
bool visible_on_add; ///< Whether to show the field when placing the symbol
bool visible_in_chooser; ///< Whether the column is shown by default in the chooser
bool show_name; ///< Whether or not to show the field name as well as its value
bool inherit_properties; ///< Whether or not to inherit properties from symbol field
};

View File

@ -282,6 +282,17 @@ protected:
return wxEmptyString;
}
/**
* Helper to retrieve a value from a JSON object (dictionary) as a certain result type
* @tparam ResultType is the type of the retrieved value.
* @param aJson is the object to act on .
* @param aKey is the object key to retrieve the value for.
* @return the result, or aDefault if aKey is not found.
*/
template<typename ResultType>
static ResultType fetchOrDefault( const nlohmann::json& aJson, const std::string& aKey,
ResultType aDefault = ResultType() );
/// The filename (not including path) of this settings file (inicode)
wxString m_filename;