54static const std::map<wxString, FAMILY>&
families()
57 static const std::map<wxString, FAMILY>
families = {
98 static const std::map<wxString, COMMON_PROPERTY> common = {
99 { wxS(
"Layer" ), {
_HKI(
"Layer" ), {
100 { wxS(
"barcode" ), wxS(
"Layer" ) },
101 { wxS(
"dimension" ), wxS(
"Layer" ) },
102 { wxS(
"shape" ), wxS(
"Layer" ) },
103 { wxS(
"table" ), wxS(
"Layer" ) },
104 { wxS(
"target" ), wxS(
"Layer" ) },
105 { wxS(
"text" ), wxS(
"Layer" ) },
106 { wxS(
"textbox" ), wxS(
"Layer" ) },
107 { wxS(
"reference_image" ), wxS(
"Associated Layer" ) } } } },
109 { wxS(
"Line Width" ), {
_HKI(
"Line Width" ), {
110 { wxS(
"route" ), wxS(
"Width" ) },
111 { wxS(
"shape" ), wxS(
"Line Width" ) },
112 { wxS(
"table" ), wxS(
"Border Width" ) },
113 { wxS(
"target" ), wxS(
"Width" ) } } } },
115 { wxS(
"Soldermask" ), {
_HKI(
"Soldermask" ), {
116 { wxS(
"route" ), wxS(
"Soldermask" ) },
117 { wxS(
"shape" ), wxS(
"Soldermask" ) } } } },
119 { wxS(
"Soldermask Margin Override" ), {
_HKI(
"Soldermask Margin Override" ), {
120 { wxS(
"pad" ), wxS(
"Soldermask Margin Override" ) },
121 { wxS(
"route" ), wxS(
"Soldermask Margin Override" ) },
122 { wxS(
"shape" ), wxS(
"Soldermask Margin Override" ) } } } },
127 { wxS(
"Font" ), {
_HKI(
"Font" ), {
128 { wxS(
"dimension" ), wxS(
"Font" ) },
129 { wxS(
"table_cell" ), wxS(
"Font" ) },
130 { wxS(
"text" ), wxS(
"Font" ) },
131 { wxS(
"textbox" ), wxS(
"Font" ) } } } },
133 { wxS(
"Text Width" ), {
_HKI(
"Text Width" ), {
134 { wxS(
"dimension" ), wxS(
"Width" ) },
135 { wxS(
"table_cell" ), wxS(
"Width" ) },
136 { wxS(
"text" ), wxS(
"Width" ) },
137 { wxS(
"textbox" ), wxS(
"Width" ) } } } },
139 { wxS(
"Text Height" ), {
_HKI(
"Text Height" ), {
140 { wxS(
"dimension" ), wxS(
"Height" ) },
141 { wxS(
"table_cell" ), wxS(
"Height" ) },
142 { wxS(
"text" ), wxS(
"Height" ) },
143 { wxS(
"textbox" ), wxS(
"Height" ) } } } },
145 { wxS(
"Text Thickness" ), {
_HKI(
"Text Thickness" ), {
146 { wxS(
"dimension" ), wxS(
"Thickness" ) },
147 { wxS(
"table_cell" ), wxS(
"Thickness" ) },
148 { wxS(
"text" ), wxS(
"Thickness" ) },
149 { wxS(
"textbox" ), wxS(
"Thickness" ) } } } },
151 { wxS(
"Bold" ), {
_HKI(
"Bold" ), {
152 { wxS(
"dimension" ), wxS(
"Bold" ) },
153 { wxS(
"table_cell" ), wxS(
"Bold" ) },
154 { wxS(
"text" ), wxS(
"Bold" ) },
155 { wxS(
"textbox" ), wxS(
"Bold" ) } } } },
157 { wxS(
"Italic" ), {
_HKI(
"Italic" ), {
158 { wxS(
"dimension" ), wxS(
"Italic" ) },
159 { wxS(
"table_cell" ), wxS(
"Italic" ) },
160 { wxS(
"text" ), wxS(
"Italic" ) },
161 { wxS(
"textbox" ), wxS(
"Italic" ) } } } },
163 { wxS(
"Horizontal Justification" ), {
_HKI(
"Horizontal Justification" ), {
164 { wxS(
"dimension" ), wxS(
"Horizontal Justification" ) },
165 { wxS(
"table_cell" ), wxS(
"Horizontal Justification" ) },
166 { wxS(
"text" ), wxS(
"Horizontal Justification" ) },
167 { wxS(
"textbox" ), wxS(
"Horizontal Justification" ) } } } },
169 { wxS(
"Vertical Justification" ), {
_HKI(
"Vertical Justification" ), {
170 { wxS(
"dimension" ), wxS(
"Vertical Justification" ) },
171 { wxS(
"table_cell" ), wxS(
"Vertical Justification" ) },
172 { wxS(
"text" ), wxS(
"Vertical Justification" ) },
173 { wxS(
"textbox" ), wxS(
"Vertical Justification" ) } } } },
175 { wxS(
"Knockout" ), {
_HKI(
"Knockout" ), {
176 { wxS(
"barcode" ), wxS(
"Knockout" ) },
177 { wxS(
"dimension" ), wxS(
"Knockout" ) },
178 { wxS(
"table_cell" ), wxS(
"Knockout" ) },
179 { wxS(
"text" ), wxS(
"Knockout" ) },
180 { wxS(
"textbox" ), wxS(
"Knockout" ) } } } }
189static const std::map<wxString, std::map<wxString, wxString>>&
commonReach();
206 return family.IsEmpty() ? wxString() : family + wxS(
"/" );
212 switch( aItem.
Type() )
233 case PCB_ZONE_T:
return static_cast<const ZONE&
>( aItem ).GetIsRuleArea() ? wxS(
"rule_area" ) : wxS(
"zone" );
234 default:
return wxEmptyString;
242 return _(
"Common to Several Kinds" );
244 auto entry =
families().find( aFamily );
246 return entry ==
families().end() ? aFamily : wxGetTranslation( entry->second.m_Label );
252 const wxString family = aKey.BeforeFirst(
'/' );
257 auto entry =
commonReach().find( aKey.AfterFirst(
'/' ) );
264 for(
const auto& [
name, property] : entry->second )
273 auto entry =
families().find( aFamily );
289 return wxGetTranslation( entry->second.m_Label );
294 const wxString
name = aKey.AfterFirst(
'/' );
296 return wxGetTranslation(
name );
308 const wxString source =
Family( aSource );
309 const wxString target =
Family( aTarget );
311 if( source.IsEmpty() || target.IsEmpty() )
314 if( source == target )
329 const std::vector<EDA_ITEM*>& aCandidates )
331 std::vector<EDA_ITEM*> targets;
333 for(
EDA_ITEM* candidate : aCandidates )
335 if( candidate && candidate != &aSource &&
Compatible( aSource, *candidate ) )
336 targets.push_back( candidate );
347 if( prefix.IsEmpty() )
350 auto it = aEnabledKeys.lower_bound( prefix );
352 if( it != aEnabledKeys.end() && it->StartsWith( prefix ) )
355 const wxString family =
Family( aItem );
369 const std::set<wxString>& aEnabledKeys )
371 std::vector<PENDING_PROPERTY> pending;
375 const bool acrossKinds = sourceFamily != targetFamily;
382 [&](
const wxString& aSourceName,
const wxString& aTargetName,
bool aOptional )
387 if( !sourceProperty || !targetProperty )
398 pending.push_back( { targetProperty, aSource.
Get( sourceProperty ), aOptional } );
405 for(
auto it = aEnabledKeys.lower_bound( prefix ); it != aEnabledKeys.end() && it->StartsWith( prefix );
408 const wxString
name = it->Mid( prefix.length() );
418 auto sourceName =
families.find( sourceFamily );
419 auto targetName =
families.find( targetFamily );
424 if( !aEnabledKeys.contains(
COMMON_FAMILY + wxS(
"/" ) + key ) )
427 stage( sourceName->second, targetName->second, acrossKinds );
435 const std::set<wxString>& aEnabledKeys )
441 result.m_Error =
_(
"The source and target have no properties in common." );
447 std::unique_ptr<EDA_ITEM> staged( aTarget.
Clone() );
448 std::vector<PENDING_PROPERTY> pending =
plan( aSource, aTarget, aEnabledKeys );
449 std::vector<std::pair<PROPERTY_BASE*, bool>> stagedProperties;
453 for(
bool madeProgress =
true; madeProgress; )
455 madeProgress =
false;
457 for(
auto it = pending.begin(); it != pending.end(); )
461 if( !mgr.
IsAvailableFor( targetType, targetProperty, staged.get() )
462 || !mgr.
IsWriteableFor( targetType, targetProperty, staged.get() ) )
468 if( !staged->Set( targetProperty, it->m_Value,
false ) )
474 it = pending.erase( it );
479 result.m_Error = wxString::Format(
_(
"Could not apply property '%s' to the target item." ),
480 wxGetTranslation( targetProperty->
Name() ) );
484 stagedProperties.push_back( { targetProperty, it->m_Optional } );
485 it = pending.erase( it );
492 std::vector<std::pair<PROPERTY_BASE*, wxAny>> apply;
494 for(
const auto& [targetProperty, optional] : stagedProperties )
496 if( !mgr.
IsAvailableFor( targetType, targetProperty, staged.get() )
497 || !mgr.
IsWriteableFor( targetType, targetProperty, staged.get() ) )
502 wxAny stagedValue = staged->Get( targetProperty );
504 if( targetProperty->Validate( wxAny( stagedValue ), staged.get() ) )
511 result.m_Error = wxString::Format(
_(
"The value for property '%s' is not valid for the target item." ),
512 wxGetTranslation( targetProperty->Name() ) );
516 apply.emplace_back( targetProperty, std::move( stagedValue ) );
519 for(
auto& [targetProperty, value] : apply )
522 && aTarget.
Set( targetProperty, value ) )
535 static const std::set<wxString> keys = []
537 std::set<wxString>
result;
543 ZONE ruleArea( &board );
546 for(
const auto& [family, entry] :
families() )
548 const TYPE_ID type = entry.m_Type;
549 const bool ruleAreaFamily = family == wxS(
"rule_area" );
553 if( !property->IsCopyable() || property->IsHiddenFromPropertiesManager() )
557 && mgr.
IsAvailableFor( type, property, &ruleArea ) != ruleAreaFamily )
562 result.insert( family + wxS(
"/" ) + property->Name() );
570 std::vector<wxString> covered;
572 for(
const auto& [family,
name] : common.m_Names )
574 const wxString familyKey = family + wxS(
"/" ) +
name;
576 if(
result.contains( familyKey ) )
577 covered.push_back( familyKey );
581 if( covered.size() < 2 )
584 for(
const wxString& familyKey : covered )
585 result.erase( familyKey );
597const std::map<wxString, std::map<wxString, wxString>>&
commonReach()
599 static const std::map<wxString, std::map<wxString, wxString>> reach = []
601 std::map<wxString, std::map<wxString, wxString>>
result;
610 for(
const auto& [family,
name] : common.m_Names )
626 static const std::set<wxString> keys = {
627 wxS(
"common/Layer" ), wxS(
"common/Line Width" ), wxS(
"shape/Fill" ),
628 wxS(
"common/Soldermask" ), wxS(
"common/Soldermask Margin Override" ),
629 wxS(
"common/Font" ), wxS(
"common/Text Width" ), wxS(
"common/Text Height" ),
630 wxS(
"common/Text Thickness" ), wxS(
"common/Bold" ), wxS(
"common/Italic" ),
631 wxS(
"shape/Line Style" ), wxS(
"via/Diameter" ), wxS(
"via/Hole" ),
632 wxS(
"zone/Fill Mode" ), wxS(
"table/Border Style" )
Information pertinent to a Pcbnew printed circuit board.
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
wxAny Get(PROPERTY_BASE *aProperty) const
bool Set(PROPERTY_BASE *aProperty, wxAny &aValue, bool aNotify=true)
For better understanding of the points that make a dimension:
Object to handle a bitmap image that can be inserted in a PCB.
bool IsHiddenFromPropertiesManager() const
bool IsCopyable() const
True for a property that says how an item looks, not what or where it is.
const wxString & Name() const
Provide class metadata.Helper macro to map type hashes to names.
const std::vector< PROPERTY_BASE * > & GetProperties(TYPE_ID aType) const
Return all properties for a specific type.
bool IsWriteableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsAvailableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
Handle a list of polygons defining a copper zone.
void SetIsRuleArea(bool aEnable)
Some functions to handle hotkeys in KiCad.
static std::vector< PENDING_PROPERTY > plan(const EDA_ITEM &aSource, const EDA_ITEM &aTarget, const std::set< wxString > &aEnabledKeys)
Target properties to write, paired with values read off the source.
static wxString familyPrefix(const EDA_ITEM &aItem)
Empty if the item has no family. Never matches a key.
static const std::map< wxString, COMMON_PROPERTY > & commonProperties()
Keyed by the name the settings use after the prefix.
static const wxString COMMON_FAMILY
The prefix common keys carry in the enabled set, in place of a family.
static const std::map< wxString, std::map< wxString, wxString > > & commonReach()
The families a common property actually reaches, once the unregistered ones are dropped.
static const std::map< wxString, FAMILY > & families()
Keyed by the names Family() returns. Every family there must appear here.
MATCH_PROPERTIES_RESULT Copy(const EDA_ITEM &aSource, EDA_ITEM &aTarget, const std::set< wxString > &aEnabledKeys)
bool Compatible(const EDA_ITEM &aSource, const EDA_ITEM &aTarget)
const std::set< wxString > & AllSafeKeys()
Every property Match Properties may copy, keyed as "family/Property Name".
bool PropertyIsRegistered(const wxString &aFamily, const wxString &aName)
Whether aFamily registers a property of that name. Used to prune the common table.
wxString PropertyLabel(const wxString &aKey)
The translated property name alone, without the family it belongs to.
const std::set< wxString > & DefaultKeys()
The subset enabled until the user says otherwise.
bool AnyEnabledFor(const EDA_ITEM &aItem, const std::set< wxString > &aEnabledKeys)
True if any enabled key names a property of this item's family.
std::vector< EDA_ITEM * > CompatibleTargets(const EDA_ITEM &aSource, const std::vector< EDA_ITEM * > &aCandidates)
wxString FamilyLabel(const wxString &aFamily)
The translated name of a family, for the heading of its group.
std::set< wxString > FamiliesFor(const wxString &aKey)
The families a key reaches. One for a family key, several for a common one.
wxString Family(const EDA_ITEM &aItem)
wxString DisplayLabel(const wxString &aKey)
BARCODE class definition.
size_t TYPE_ID
Unique type identifier.
A property that means the same thing in more than one family.
std::map< wxString, wxString > m_Names
family -> the name it is registered under there
TYPE_ID m_Type
One item type carrying every property the family advertises.
One value staged for the target. Optional entries are dropped if they will not go.
PROPERTY_BASE * m_Property
wxString result
Test unit parsing edge cases and error handling.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
bool KiWxAnyEquals(const wxAny &aA, const wxAny &aB, const PROPERTY_BASE *aProperty)
Compare two wxAny values for equality across the KiCad property type set.