22#include <wx/settings.h>
45 const wxString& aFieldName,
58 aValue = field->GetText();
77 const wxString& aFieldName,
78 wxString& aValue )
const
87 if( !aValue.IsEmpty() || ( !keywords && ( !field || !field->
IsMandatory() ) ) )
90 std::set<const LIB_SYMBOL*> visited{ aSymbol };
91 std::shared_ptr<LIB_SYMBOL> parent = aSymbol->
GetParent().lock();
93 while( parent && visited.insert( parent.get() ).second )
98 aValue = parent->GetRawKeyWords();
99 else if(
const SCH_FIELD* parentField = parent->GetField( aFieldName ) )
100 aValue = parentField->GetText();
102 if( !aValue.IsEmpty() )
105 parent = parent->GetParent().lock();
118 wxCHECK_RET( aRow >= 0 && aRow < (
int)
m_rows.size(), wxS(
"Invalid row number" ) );
119 wxCHECK_RET( aCol >= 0 && aCol < (
int)
m_cols.size(), wxS(
"Invalid column number" ) );
128 const wxString& fieldName =
m_cols[aCol].m_fieldName;
136 if( aValue == wxS(
"1" ) )
171 if( !child->IsDerived() )
174 std::shared_ptr<LIB_SYMBOL> root = child->GetRootSymbol();
177 if( !root || root->m_Uuid != symbol->m_Uuid )
182 isPower && localPower == wxS(
"1" ) ? wxS(
"1" ) : wxS(
"0" ) );
193 GetView()->ForceRefresh();
199 wxCHECK( aRow >= 0 && aRow <
static_cast<int>(
m_rows.size() ),
false );
200 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
206 const wxString& fieldName =
m_cols[aCol].m_fieldName;
207 bool hasOverride =
false;
212 if( !symbol->IsDerived() )
215 const SCH_FIELD* field = symbol->GetField( fieldName );
222 hasOverride |= !value.IsEmpty();
232 SetValue( aRow, aCol, wxEmptyString );
238 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
266 if( symbol->IsDerived() )
297 wxGridCellAttr* attr = wxGridTableBase::GetAttr( aRow, aCol, aKind );
303 wxString storedValue;
304 wxString effectiveValue;
308 if( storedValue != effectiveValue )
309 needsResolvedTextRenderer =
true;
312 wxGridCellAttr* modelAttr =
nullptr;
324 if( attr->HasBackgroundColour() && !modelAttr->HasBackgroundColour() )
325 modelAttr->SetBackgroundColour( attr->GetBackgroundColour() );
326 if( attr->HasTextColour() && !modelAttr->HasTextColour() )
327 modelAttr->SetTextColour( attr->GetTextColour() );
328 if( attr->HasFont() && !modelAttr->HasFont() )
329 modelAttr->SetFont( attr->GetFont() );
338 attr =
new wxGridCellAttr;
344 bool rowModified =
false;
345 bool cellModified =
false;
346 bool cellEmpty =
true;
347 bool blankModified =
false;
349 const wxString& fieldName =
m_cols[aCol].m_fieldName;
354 wxString storedValue;
357 bool modified = liveFieldPresent != storedFieldPresent || liveValue != storedValue;
362 bool elementEmpty = !storedFieldPresent || ( !liveFieldPresent && !modified );
367 if( storedValue.IsEmpty() && modified )
368 blankModified =
true;
382 if( cellModified && rowModified && !cellEmpty )
388 attr->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
393 wxString storedValue;
396 bool modified = liveFieldPresent != storedFieldPresent || liveValue != storedValue;
400 if( !storedFieldPresent )
402 if( !liveFieldPresent )
404 attr->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
406 else if( liveValue.empty() )
415 else if( storedValue.IsEmpty() )
429 attr->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
435 if( needsResolvedTextRenderer )
442 if( attr->HasFont() )
443 font = attr->GetFont();
445 font = GetView()->GetDefaultCellFont();
452 attr->SetFont( font );
461 wxString& aNewSymbolName )
463 wxCHECK_RET( aRow >= 0 && aRow < (
int)
m_rows.size(),
"Invalid Row Number" );
464 wxCHECK_RET( aCol >= 0 && aCol < (
int)
m_cols.size(),
"Invalid Column Number" );
468 wxLogTrace(
traceLibFieldTable,
"CreateDerivedSymbolImmediate: Creating '%s' from parent '%s' immediately",
469 aNewSymbolName, parentSymbol->
GetName() );
472 KIID newDerivedSymbolUuid;
485 wxLogTrace(
traceLibFieldTable,
"createActualDerivedSymbol: Creating '%s' from parent '%s', symbol list size before: %zu",
492 if( sym->m_Uuid == aNewSymbolUuid )
502 newSymbol->
SetName( aNewSymbolName );
509 const_cast<KIID&
>( newSymbol->
m_Uuid ) = aNewSymbolUuid;
512 wxLogTrace(
traceLibFieldTable,
"createActualDerivedSymbol: Added new symbol to list, size now: %zu",
518 wxLogTrace(
traceLibFieldTable,
"createActualDerivedSymbol: Initialized field data for new symbol" );
525 wxLogTrace(
traceLibFieldTable,
"Created derived symbol '%s' for library '%s', total tracked: %zu",
530 const wxString& aAttributeName )
532 if( aAttributeName == wxS(
"${DNP}" ) )
533 return aSymbol->
GetDNP() ? wxS(
"1" ) : wxS(
"0" );
535 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
538 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
541 if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
544 if( aAttributeName == wxS(
"${EXCLUDE_FROM_POS_FILES}" ) )
548 return aSymbol->
IsPower() ? wxS(
"1" ) : wxS(
"0" );
551 return aSymbol->
IsLocalPower() ? wxS(
"1" ) : wxS(
"0" );
558 const wxString& aAttributeName,
559 const wxString& aValue )
561 if( aAttributeName == wxS(
"${DNP}" ) )
562 aSymbol->
SetDNP( aValue == wxS(
"1" ) );
563 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
565 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
567 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
569 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_POS_FILES}" ) )
577 || aFieldName == wxS(
"${EXCLUDE_FROM_BOARD}" )
578 || aFieldName == wxS(
"${EXCLUDE_FROM_BOM}" )
579 || aFieldName == wxS(
"${EXCLUDE_FROM_POS_FILES}" )
580 || aFieldName == wxS(
"${EXCLUDE_FROM_SIM}" );
589 return value == wxS(
"1" );
599 static const std::vector<wxString> exclusionFields = {
600 wxS(
"${EXCLUDE_FROM_BOARD}" ),
601 wxS(
"${EXCLUDE_FROM_BOM}" ),
602 wxS(
"${EXCLUDE_FROM_POS_FILES}" ),
603 wxS(
"${EXCLUDE_FROM_SIM}" ),
606 for(
const wxString& fieldName : exclusionFields )
617 return wxEmptyString;
620 return wxS(
"Power Symbol" );
622 return wxS(
"Local Power Symbol" );
639 static_cast<WX_GRID*
>( GetView() )->CommitPendingChanges(
true );
641 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, (
int)
m_rows.size() );
642 GetView()->ProcessTableMessage( msg );
651 bool groupByParent = parentCol >= 0 &&
GetGroupColumn( parentCol );
657 if( col.m_group && col.m_fieldName !=
SYMBOL_ROOT )
658 groupByRootOnly =
false;
664 symbol->GetName(), symbol->m_Uuid.AsString() );
666 if(
m_scope == SCOPE::SCOPE_RELATED_SYMBOLS )
668 std::shared_ptr<LIB_SYMBOL> root = symbol->GetRootSymbol();
683 bool matchFound =
false;
702 row.m_items.push_back( symbol );
703 row.m_state = ROW_STATE::GROUP_COLLAPSED;
712 if( groupByRootOnly )
716 std::vector<LIB_FIELDS_TABLE_DATA_MODEL_ROW>
families;
720 auto root = std::find_if( row.m_items.begin(), row.m_items.end(),
723 return aSymbol->IsRoot();
726 if( root == row.m_items.end() )
731 families.emplace_back( symbol, ROW_STATE::NON_EXPANDABLE );
737 std::iter_swap( row.m_items.begin(), root );
739 if( row.m_items.size() > 1 )
740 row.m_state = ROW_STATE::PARENT_COLLAPSED;
750 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
751 GetView()->ProcessTableMessage( msg );
761 return lhItem == rhItem;
766 const wxString& aFieldName )
773 return wxEmptyString;
784 std::function<bool( wxString* )> libSymbolResolver =
785 [&]( wxString* token ) ->
bool
793 return wxEmptyString;
801 std::function<bool( wxString* )> libSymbolResolver =
802 [&]( wxString* token ) ->
bool
815 std::function<
void()> postApplyHandler )
819 std::set<LIB_SYMBOL*> modifiedSymbols;
825 if( symbol->IsDerived() )
828 bool symbolIsPower = symbol->IsPower();
829 bool symbolIsLocalPower = symbol->IsLocalPower();
835 if( localPowerCol != -1 )
838 && value == wxS(
"1" );
843 if( powerCol != -1 && !symbolIsPower )
844 symbolIsLocalPower =
false;
845 else if( symbolIsLocalPower )
846 symbolIsPower =
true;
848 if( symbol->IsPower() != symbolIsPower || symbol->IsLocalPower() != symbolIsLocalPower )
850 if( symbolIsLocalPower )
851 symbol->SetLocalPower();
852 else if( symbolIsPower )
853 symbol->SetGlobalPower();
857 modifiedSymbols.insert( symbol );
863 bool symbolModified = modifiedSymbols.contains( symbol );
864 const bool symbolIsPower = symbol->IsPower();
866 for(
size_t i = 0; i <
m_cols.size(); ++i )
882 wxString newValue = currentlyPresent ? srcValue : wxString( wxS(
"0" ) );
887 symbolModified =
true;
895 if( symbol->GetRawKeyWords() != srcValue )
897 symbol->SetKeyWords( srcValue );
898 symbolModified =
true;
909 SCH_FIELD* destField = symbol->GetField( srcName );
911 if( !currentlyPresent && destField )
918 destField->
SetText( wxEmptyString );
919 symbolModified =
true;
924 symbol->RemoveField( destField );
925 symbolModified =
true;
933 bool createField = !destField && currentlyPresent;
937 const VECTOR2I symbolPos = symbol->GetPosition();
940 symbol->AddField( destField );
941 symbolModified =
true;
950 wxString newValue = symbolIsPower ? symbol->GetName() : srcValue;
952 if( !newValue.IsEmpty() && destField->
GetText() != newValue )
955 symbolModified =
true;
958 else if( destField->
GetText() != srcValue )
960 destField->
SetText( srcValue );
961 symbolModified =
true;
965 std::vector<SCH_FIELD*> symbolFields;
966 symbol->GetFields( symbolFields );
971 if( field->IsMandatory() || field->IsPrivate() )
974 const wxString& existingName = field->GetName();
980 symbol->RemoveField( field );
981 symbolModified =
true;
986 modifiedSymbols.insert( symbol );
993 std::stable_sort( symbols.begin(), symbols.end(),
996 return aLeft->GetInheritanceDepth() < aRight->GetInheritanceDepth();
1002 symbol->RefreshLibraryTreeCaches();
1004 if( modifiedSymbols.contains( symbol ) )
1005 symbolChangeHandler( symbol );
1013 if( postApplyHandler )
1028 if( symbol->IsDerived() && reference.IsEmpty() )
1033 if( !aErrorMessage.IsEmpty() )
1047 return wxGRID_VALUE_BOOL;
1049 return wxGridTableBase::GetTypeName( row, col );
1056 key.push_back( aItem->
m_Uuid );
bool cellUsesResolvedTextRenderer(int aRow, int aCol)
virtual bool fieldIsItemProperty(const wxString &aFieldName) const
bool cellUsesUrlEditor(int aRow, int aCol)
std::map< KIID_PATH, std::map< wxString, FIELD_STORE_VALUE > > m_dataStore
bool ColIsValue(int aCol) const
bool ColIsAttribute(int aCol) const
void applyResolvedTextRenderer(wxGridCellAttr *aAttr, bool aApplyTint)
bool GetGroupColumn(int aCol)
wxGridCellAttr * cloneUrlEditorAttr()
virtual bool fieldIsAttribute(const wxString &aFieldName) const
wxGridCellAttr * applyCellDecorations(wxGridCellAttr *aAttr, int aRow, int aCol)
virtual wxString getAttributeResolvedValue(const wxString &aFieldName, bool aValue) const
int GetFieldNameCol(const wxString &aFieldName) const
std::vector< DATA_MODEL_COL > m_cols
bool groupMatch(const LIB_SYMBOL *&lhItem, const LIB_SYMBOL *&rhItem)
void setStoredFieldValue(const LIB_SYMBOL *&aItem, const wxString &aFieldName, const wxString &aValue)
bool fieldIsModified(const LIB_SYMBOL *&aItem, const wxString &aFieldName)
void initializeDataStoreItem(const LIB_SYMBOL *&aItem)
bool getStoredFieldValue(const LIB_SYMBOL *&aItem, const wxString &aFieldName, wxString &aValue) const
std::vector< DATA_MODEL_ROW< LIB_SYMBOL * > > m_rows
bool resolveStoredTextVar(const LIB_SYMBOL *&aItem, wxString *aToken, bool aCaseSensitive=false) const
bool IsCellReadOnly(int aRow, int aCol) override
bool MatchesFilter(const LIB_SYMBOL *&aItem, const wxString &aReference, EDA_COMBINED_MATCHER &aMatcher)
void acceptDataStoreItem(const LIB_SYMBOL *&aItem)
static const wxString SYMBOL_KEYWORDS
void UseParentValue(int aRow, int aCol)
bool fieldIsItemProperty(const wxString &aFieldName) const override
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxString getAttributeResolvedValue(const wxString &aFieldName, bool aValue) const override
wxString getAttributeValue(const LIB_SYMBOL *, const wxString &aAttributeName)
std::vector< std::pair< LIB_SYMBOL *, wxString > > m_createdDerivedSymbols
std::vector< LIB_SYMBOL * > getAllItems() const override
bool IsCellReadOnly(int aRow, int aCol) override
KIID_PATH getDataStoreKey(LIB_SYMBOL *const &aItem) const override
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) override
void RebuildRows() override
static const wxString SYMBOL_NAME
static const wxString SYMBOL_IS_POWER
bool ColIsItemIdentifier(int aCol) const override
Reference for symbol/fields tables, lib_id for lib tables.
void CreateDerivedSymbolImmediate(int aRow, int aCol, wxString &aNewSymbolName)
bool getStoredPowerSymbolValue(LIB_SYMBOL *aSymbol) const
wxString getFieldResolvedLiveValue(LIB_SYMBOL *const &aSymbol, const wxString &aFieldName) override
Explicitly bypasses the data store's field values and retries them from the item's current field valu...
void createActualDerivedSymbol(const LIB_SYMBOL *aParentSymbol, const wxString &aNewSymbolName, const KIID &aNewSymbolUuid)
bool fieldIsAttribute(const wxString &aFieldName) const override
void ApplyData(std::function< void(LIB_SYMBOL *)> symbolChangeHandler, std::function< void()> postApplyHandler=nullptr)
static const wxString SYMBOL_IS_LOCAL_POWER
static const wxString SYMBOL_PARENT
std::vector< LIB_SYMBOL * > m_symbolsList
bool CanUseParentValue(int aRow, int aCol)
void setAttributeValue(LIB_SYMBOL *aSymbol, const wxString &aAttributeName, const wxString &aValue)
bool unitMatch(LIB_SYMBOL *const &lhItem, LIB_SYMBOL *const &rhItem) override
bool getLiveFieldValue(LIB_SYMBOL *const &aSymbol, const wxString &aFieldName, wxString &aValue) override
Gets the current value of the field from the live item, e.g.
wxString getItemIdentifier(LIB_SYMBOL *const &aItem) const override
wxString GetTypeName(int row, int col) override
bool isPowerSymbolControlledField(const wxString &aFieldName) const
wxString resolveTextVars(LIB_SYMBOL *const &aSymbol, const wxString &aText) override
wxString m_relatedSymbolRoot
static const wxString SYMBOL_ROOT
void setPowerSymbolDefaults(LIB_SYMBOL *aSymbol)
void getEffectiveFieldValue(LIB_SYMBOL *const &aSymbol, const wxString &aFieldName, wxString &aValue) const override
bool ValidateReferences(wxString &aSymbolName, wxString &aErrorMessage) const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Define a library symbol object.
const wxString & GetRawKeyWords() const
Return only this symbol's keywords, without inheriting from its parent.
const LIB_ID & GetLibId() const override
std::weak_ptr< LIB_SYMBOL > & GetParent()
bool IsPower() const override
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
void SetParent(LIB_SYMBOL *aParent=nullptr)
wxString GetName() const override
SCH_FIELD & GetValueField()
bool IsLocalPower() const override
bool ResolveTextVar(wxString *aToken, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
virtual void SetName(const wxString &aName)
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
bool GetExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void SetExcludedFromBoard(bool aExclude, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear exclude from board netlist flag.
virtual bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
virtual void SetExcludedFromSim(bool aExcludeFromSim, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from simulation flag.
virtual bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
virtual void SetDNP(bool aDNP, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void SetExcludedFromPosFiles(bool aExclude, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear exclude from position files flag.
virtual bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
virtual void SetExcludedFromBOM(bool aExcludeFromBOM, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
std::map< int, wxGridCellAttr * > m_colAttrs
bool IsGeneratedField(const wxString &aFieldName)
Returns true if the entire string is generated, e.g is a single text var reference.
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
const wxChar *const traceLibFieldTable
DATA_MODEL_ROW< LIB_SYMBOL * > LIB_FIELDS_TABLE_DATA_MODEL_ROW
static const std::map< wxString, FAMILY > & families()
Keyed by the names Family() returns. Every family there must appear here.
const wxColour STRIPED_CLEARED_EMPTY_FIELD_LIGHT_GREEN(180, 220, 180)
const wxColour STRIPED_EDITED_EMPTY_FIELD_MUTED_GREEN(180, 200, 180)
const wxColour EDITED_EMPTY_FIELD_BRIGHT_GREEN(192, 255, 192)
const wxColour STRIPED_EDITED_NONEMPTY_FIELD_MUTED_RED(200, 180, 180)
const wxColour STRIPED_CLEARED_NONEMPTY_FIELD_LIGHT_RED(220, 180, 180)
wxString UnescapeString(const wxString &aSource)
The point of the data model classes is fundamentally to represent three things:
std::span< const ITEM_TYPE > GetCellItems() const
Items displayed and edited by this row, excluding descendants of a real parent.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
@ USER
The field ID hasn't been set yet; field is invalid.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxLogTrace helper definitions.
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
wxString GetFieldValidationErrorMessage(FIELD_T aFieldId, const wxString &aValue)
Return the error message if aValue is invalid for aFieldId.
Custom text control validator definitions.
VECTOR2< int32_t > VECTOR2I