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"]; const nlohmann::json& pj = entry["properties"];
if( pj.contains( "description" ) ) table.properties.description = fetchOrDefault<std::string>( pj, "description" );
table.properties.description = pj["description"].get<std::string>();
if( pj.contains( "footprint_filters" ) )
{
table.properties.footprint_filters = table.properties.footprint_filters =
pj["footprint_filters"].get<std::string>(); fetchOrDefault<std::string>( pj, "footprint_filters" );
}
if( pj.contains( "keywords" ) ) table.properties.keywords = fetchOrDefault<std::string>( pj, "keywords" );
table.properties.keywords = pj["keywords"].get<std::string>();
if( pj.contains( "exclude_from_bom" ) )
{
table.properties.exclude_from_bom = table.properties.exclude_from_bom =
pj["exclude_from_bom"].get<std::string>(); fetchOrDefault<std::string>( pj, "exclude_from_bom" );
}
if( pj.contains( "exclude_from_board" ) )
{
table.properties.exclude_from_board = table.properties.exclude_from_board =
pj["exclude_from_board"].get<std::string>(); fetchOrDefault<std::string>( pj, "exclude_from_board" );
}
} }
if( entry.contains( "fields" ) && entry["fields"].is_array() ) 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() ) if( fieldJson.empty() || !fieldJson.is_object() )
continue; continue;
std::string column = fieldJson.contains( "column" ) std::string column = fetchOrDefault<std::string>( fieldJson, "column" );
? fieldJson["column"].get<std::string>() : ""; std::string name = fetchOrDefault<std::string>( fieldJson, "name" );
bool visible_on_add = fetchOrDefault<bool>( fieldJson, "visible_on_add" );
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>();
bool visible_in_chooser = bool visible_in_chooser =
!fieldJson.contains( "visible_in_chooser" ) fetchOrDefault<bool>( fieldJson, "visible_in_chooser" );
|| fieldJson["visible_in_chooser"].get<bool>(); bool show_name = fetchOrDefault<bool>( fieldJson, "show_name" );
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
bool show_name = fieldJson.contains( "show_name" )
&& fieldJson["show_name"].get<bool>();
table.fields.emplace_back( table.fields.emplace_back(
DATABASE_FIELD_MAPPING( 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 ); 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 <iostream>
#include <unordered_set>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -349,6 +350,14 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
symbol->SetIncludeInBom( !exclude ); 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 ) for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
{ {
if( !aRow.count( mapping.column ) ) if( !aRow.count( mapping.column ) )
@ -382,13 +391,31 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
continue; continue;
} }
LIB_FIELD* field = new LIB_FIELD( symbol->GetNextAvailableFieldId() ); LIB_FIELD* field;
bool isNew = false;
if( fieldsMap.count( mapping.name ) )
{
field = fieldsMap[mapping.name];
}
else
{
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
field->SetName( mapping.name ); field->SetName( mapping.name );
field->SetText( value ); isNew = true;
fieldsMap[mapping.name] = field;
}
if( !mapping.inherit_properties || isNew )
{
field->SetVisible( mapping.visible_on_add ); field->SetVisible( mapping.visible_on_add );
field->SetAutoAdded( true ); field->SetAutoAdded( true );
field->SetNameShown( mapping.show_name ); field->SetNameShown( mapping.show_name );
}
field->SetText( value );
if( isNew )
symbol->AddField( field ); symbol->AddField( field );
m_customFields.insert( mapping.name ); 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_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 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 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; 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) /// The filename (not including path) of this settings file (inicode)
wxString m_filename; wxString m_filename;