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}" ) )
572 wxLogDebug(
"Unknown attribute name: %s", aAttributeName );
579 || aFieldName == wxS(
"${EXCLUDE_FROM_BOARD}" )
580 || aFieldName == wxS(
"${EXCLUDE_FROM_BOM}" )
581 || aFieldName == wxS(
"${EXCLUDE_FROM_POS_FILES}" )
582 || aFieldName == wxS(
"${EXCLUDE_FROM_SIM}" );
591 return value == wxS(
"1" );
601 static const std::vector<wxString> exclusionFields = {
602 wxS(
"${EXCLUDE_FROM_BOARD}" ),
603 wxS(
"${EXCLUDE_FROM_BOM}" ),
604 wxS(
"${EXCLUDE_FROM_POS_FILES}" ),
605 wxS(
"${EXCLUDE_FROM_SIM}" ),
608 for(
const wxString& fieldName : exclusionFields )
619 return wxEmptyString;
622 return wxS(
"Power Symbol" );
624 return wxS(
"Local Power Symbol" );
641 static_cast<WX_GRID*
>( GetView() )->CommitPendingChanges(
true );
643 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, (
int)
m_rows.size() );
644 GetView()->ProcessTableMessage( msg );
653 bool groupByParent = parentCol >= 0 &&
GetGroupColumn( parentCol );
659 if( col.m_group && col.m_fieldName !=
SYMBOL_ROOT )
660 groupByRootOnly =
false;
666 symbol->GetName(), symbol->m_Uuid.AsString() );
668 if(
m_scope == SCOPE::SCOPE_RELATED_SYMBOLS )
670 std::shared_ptr<LIB_SYMBOL> root = symbol->GetRootSymbol();
685 bool matchFound =
false;
704 row.m_items.push_back( symbol );
705 row.m_state = ROW_STATE::GROUP_COLLAPSED;
714 if( groupByRootOnly )
718 std::vector<LIB_FIELDS_TABLE_DATA_MODEL_ROW>
families;
722 auto root = std::find_if( row.m_items.begin(), row.m_items.end(),
725 return aSymbol->IsRoot();
728 if( root == row.m_items.end() )
733 families.emplace_back( symbol, ROW_STATE::NON_EXPANDABLE );
739 std::iter_swap( row.m_items.begin(), root );
741 if( row.m_items.size() > 1 )
742 row.m_state = ROW_STATE::PARENT_COLLAPSED;
752 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
753 GetView()->ProcessTableMessage( msg );
763 return lhItem == rhItem;
768 const wxString& aFieldName )
775 return wxEmptyString;
786 std::function<bool( wxString* )> libSymbolResolver =
787 [&]( wxString* token ) ->
bool
795 return wxEmptyString;
803 std::function<bool( wxString* )> libSymbolResolver =
804 [&]( wxString* token ) ->
bool
817 std::function<
void()> postApplyHandler )
821 std::set<LIB_SYMBOL*> modifiedSymbols;
827 if( symbol->IsDerived() )
830 bool symbolIsPower = symbol->IsPower();
831 bool symbolIsLocalPower = symbol->IsLocalPower();
837 if( localPowerCol != -1 )
840 && value == wxS(
"1" );
845 if( powerCol != -1 && !symbolIsPower )
846 symbolIsLocalPower =
false;
847 else if( symbolIsLocalPower )
848 symbolIsPower =
true;
850 if( symbol->IsPower() != symbolIsPower || symbol->IsLocalPower() != symbolIsLocalPower )
852 if( symbolIsLocalPower )
853 symbol->SetLocalPower();
854 else if( symbolIsPower )
855 symbol->SetGlobalPower();
859 modifiedSymbols.insert( symbol );
865 bool symbolModified = modifiedSymbols.contains( symbol );
866 const bool symbolIsPower = symbol->IsPower();
868 for(
size_t i = 0; i <
m_cols.size(); ++i )
884 wxString newValue = currentlyPresent ? srcValue : wxString( wxS(
"0" ) );
889 symbolModified =
true;
897 if( symbol->GetRawKeyWords() != srcValue )
899 symbol->SetKeyWords( srcValue );
900 symbolModified =
true;
911 SCH_FIELD* destField = symbol->GetField( srcName );
913 if( !currentlyPresent && destField )
920 destField->
SetText( wxEmptyString );
921 symbolModified =
true;
926 symbol->RemoveField( destField );
927 symbolModified =
true;
935 bool createField = !destField && currentlyPresent;
939 const VECTOR2I symbolPos = symbol->GetPosition();
942 symbol->AddField( destField );
943 symbolModified =
true;
952 wxString newValue = symbolIsPower ? symbol->GetName() : srcValue;
954 if( !newValue.IsEmpty() && destField->
GetText() != newValue )
957 symbolModified =
true;
960 else if( destField->
GetText() != srcValue )
962 destField->
SetText( srcValue );
963 symbolModified =
true;
967 std::vector<SCH_FIELD*> symbolFields;
968 symbol->GetFields( symbolFields );
973 if( field->IsMandatory() || field->IsPrivate() )
976 const wxString& existingName = field->GetName();
982 symbol->RemoveField( field );
983 symbolModified =
true;
988 modifiedSymbols.insert( symbol );
995 std::stable_sort( symbols.begin(), symbols.end(),
998 return aLeft->GetInheritanceDepth() < aRight->GetInheritanceDepth();
1004 symbol->RefreshLibraryTreeCaches();
1006 if( modifiedSymbols.contains( symbol ) )
1007 symbolChangeHandler( symbol );
1015 if( postApplyHandler )
1030 if( symbol->IsDerived() && reference.IsEmpty() )
1035 if( !aErrorMessage.IsEmpty() )
1049 return wxGRID_VALUE_BOOL;
1051 return wxGridTableBase::GetTypeName( row, col );
1058 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