44 m_cols.push_back( { aFieldName, aLabel, aAddedByUser,
false,
false } );
55 const wxString& aFieldName )
63 if( field->IsPrivate() )
106 node.key() = newName;
111 m_cols[aCol].m_fieldName = newName;
112 m_cols[aCol].m_label = newName;
118 for(
size_t i = 0; i <
m_cols.size(); i++ )
120 if(
m_cols[i].m_fieldName == aFieldName )
121 return static_cast<int>( i );
130 std::vector<BOM_FIELD> fields;
133 fields.push_back( { col.m_fieldName, col.m_label, col.m_show, col.m_group } );
141 if( aNewOrder.size() ==
m_cols.size() )
143 size_t foundCount = 0;
145 for(
const wxString& newField : aNewOrder )
149 if( col.m_fieldName == newField )
151 std::swap(
m_cols[foundCount], col );
182 wxGridCellAttr::wxAttrKind aKind )
205 const wxString& refDelimiter,
206 const wxString& refRangeDelimiter,
208 bool listMixedValues )
210 std::vector<SCH_REFERENCE> references;
211 std::set<wxString> mixedValues;
218 references.push_back( ref );
240 else if( refFieldValue.Contains( wxT(
"${" ) ) )
244 std::function<bool( wxString* )> symbolResolver =
245 [&]( wxString* token ) ->
bool
250 refFieldValue =
ExpandTextVars( refFieldValue, & symbolResolver );
254 if( listMixedValues )
255 mixedValues.insert( refFieldValue );
256 else if( &ref == &
group.m_Refs.front() )
257 fieldValue = refFieldValue;
258 else if( fieldValue != refFieldValue )
263 if( listMixedValues )
265 fieldValue = wxEmptyString;
267 for(
const wxString& value : mixedValues )
269 if( value.IsEmpty() )
271 else if( fieldValue.IsEmpty() )
274 fieldValue +=
"," + value;
281 std::sort( references.begin(), references.end(),
284 wxString l_ref( l.GetRef() << l.GetRefNumber() );
285 wxString r_ref( r.GetRef() << r.GetRefNumber() );
286 return StrNumCmp( l_ref, r_ref, true ) < 0;
289 auto logicalEnd = std::unique( references.begin(), references.end(),
294 if( l.GetRefNumber() == wxT(
"?" ) )
297 wxString l_ref( l.GetRef() << l.GetRefNumber() );
298 wxString r_ref( r.GetRef() << r.GetRefNumber() );
299 return l_ref == r_ref;
302 references.erase( logicalEnd, references.end() );
308 fieldValue = wxString::Format( wxT(
"%d" ), (
int) references.size() );
310 fieldValue = wxString::Format( wxT(
"%d" ),
group.m_ItemNumber );
318 wxCHECK_RET( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ), wxS(
"Invalid column number" ) );
338 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
345 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
352 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
359 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
366 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
377 if( lhGroup.
m_Refs.size() == 0 )
379 else if( rhGroup.
m_Refs.size() == 0 )
385 [ ascending ](
const auto a,
const auto b )
395 wxString lhs = dataModel->
GetValue( lhGroup, sortCol ).Trim(
true ).Trim(
false );
396 wxString rhs = dataModel->
GetValue( rhGroup, sortCol ).Trim(
true ).Trim(
false );
400 wxString lhRef = lhGroup.
m_Refs[0].GetRef() + lhGroup.
m_Refs[0].GetRefNumber();
401 wxString rhRef = rhGroup.
m_Refs[0].GetRef() + rhGroup.
m_Refs[0].GetRefNumber();
402 return local_cmp(
StrNumCmp( lhRef, rhRef,
true ), 0 );
419 std::sort( row.m_Refs.begin(), row.m_Refs.end(),
422 wxString lhs_ref( lhs.GetRef() << lhs.GetRefNumber() );
423 wxString rhs_ref( rhs.GetRef() << rhs.GetRefNumber() );
424 return StrNumCmp( lhs_ref, rhs_ref, true ) < 0;
431 return cmp( lhs, rhs, this, m_sortColumn, m_sortAscending );
438 row.m_ItemNumber = itemNumber++;
461 bool matchFound =
false;
468 if(
m_cols[refCol].m_group )
481 for(
size_t i = 0; i <
m_cols.size(); ++i )
484 if(
static_cast<int>( i ) == refCol )
515 wxString fieldName =
m_cols[i].m_fieldName;
528 const wxString& aFieldName )
535 return wxEmptyString;
547 std::function<bool( wxString* )> symbolResolver =
548 [&]( wxString* token ) ->
bool
556 return wxEmptyString;
562 return aFieldName == wxS(
"${DNP}" )
563 || aFieldName == wxS(
"${EXCLUDE_FROM_BOARD}" )
564 || aFieldName == wxS(
"${EXCLUDE_FROM_BOM}" )
565 || aFieldName == wxS(
"${EXCLUDE_FROM_SIM}" );
570 const wxString& aAttributeName )
572 if( aAttributeName == wxS(
"${DNP}" ) )
573 return aSymbol.
GetDNP() ? wxS(
"1" ) : wxS(
"0" );
575 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
578 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
581 if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
588 const wxString& aAttributeName,
589 const wxString& aValue )
591 if( aAttributeName == wxS(
"${DNP}" ) )
592 aSymbol.
SetDNP( aValue == wxS(
"1" ) );
593 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
595 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
597 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
623 static_cast<WX_GRID*
>( GetView() )->CommitPendingChanges(
true );
625 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
626 GetView()->ProcessTableMessage( msg );
655 || (
m_scope == SCOPE::SCOPE_SHEET_RECURSIVE
661 bool matchFound =
false;
679 row.m_Refs.push_back( ref );
685 row.m_Refs.push_back( ref );
697 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
m_rows.size() );
698 GetView()->ProcessTableMessage( msg );
707 std::vector<DATA_MODEL_ROW> children;
711 bool matchFound =
false;
721 child.m_Refs.push_back( ref );
730 if( children.size() < 2 )
733 std::sort( children.begin(), children.end(),
736 return cmp( lhs, rhs, this, m_sortColumn, m_sortAscending );
740 m_rows.insert(
m_rows.begin() + aRow + 1, children.begin(), children.end() );
742 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, aRow, children.size() );
743 GetView()->ProcessTableMessage( msg );
749 auto firstChild =
m_rows.begin() + aRow + 1;
750 auto afterLastChild = firstChild;
753 while( afterLastChild !=
m_rows.end() && afterLastChild->m_Flag ==
CHILD_ITEM )
760 m_rows.erase( firstChild, afterLastChild );
762 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow + 1, deleted );
763 GetView()->ProcessTableMessage( msg );
780 for(
size_t i = 0; i <
m_rows.size(); ++i )
793 for(
size_t i = 0; i <
m_rows.size(); ++i )
809 aCommit.
Modify( &symbol, instance.GetSheetPath().LastScreen() );
813 for(
const auto& [srcName, srcValue] : fieldStore )
829 if( destField && destField->
IsPrivate() )
831 if( srcValue.IsEmpty() )
838 bool userAdded = ( col != -1 &&
m_cols[col].m_userAdded );
841 bool createField = !destField && ( !srcValue.IsEmpty() || userAdded );
846 &symbol, srcName ) );
847 destField->
SetTextAngle( symbol.GetField( FIELD_T::REFERENCE )->GetTextAngle() );
856 if( destField->
GetId() == FIELD_T::REFERENCE )
865 for(
int ii =
static_cast<int>( symbol.
GetFields().size() ) - 1; ii >= 0; ii-- )
870 if( fieldStore.count( symbol.
GetFields()[ii].GetName() ) == 0 )
908 for(
size_t i = 0; i <
m_cols.size(); i++ )
914 std::set<wxString> seen;
915 std::vector<wxString> order;
921 if( !field.
name || seen.count( field.
name ) )
924 seen.insert( field.
name );
925 order.emplace_back( field.
name );
992 for(
size_t col = 0; col <
m_cols.size(); col++ )
995 last_col =
static_cast<int>( col );
1003 [&]( wxString field,
bool last ) -> wxString
1007 field.Replace( wxS(
"\r" ), wxS(
"" ) );
1008 field.Replace( wxS(
"\n" ), wxS(
"" ) );
1013 field.Replace( wxS(
"\t" ), wxS(
"" ) );
1027 for(
size_t col = 0; col <
m_cols.size(); col++ )
1029 if( !
m_cols[col].m_show )
1032 out.Append( formatField(
m_cols[col].m_label, col ==
static_cast<size_t>( last_col ) ) );
1036 for(
size_t row = 0; row <
m_rows.size(); row++ )
1042 for(
size_t col = 0; col <
m_cols.size(); col++ )
1044 if( !
m_cols[col].m_show )
1048 out.Append( formatField(
GetExportValue(
static_cast<int>( row ),
static_cast<int>( col ),
1050 col ==
static_cast<size_t>( last_col ) ) );
1071 if( !field.IsPrivate() )
1073 wxString
name = field.GetCanonicalName();
1095 return ref.GetSymbol()->m_Uuid == aSymbol.m_Uuid;
1112 if( ref.GetSymbol()->GetInstances().empty() )
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual void SetVisible(bool aVisible)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetFieldNameCol(const wxString &aFieldName) const
wxString GetColFieldName(int aCol)
std::vector< DATA_MODEL_ROW > m_rows
void ApplyBomPreset(const BOM_PRESET &preset)
void SetFieldsOrder(const std::vector< wxString > &aNewOrder)
SCH_REFERENCE_LIST m_symbolsList
void SetGroupingEnabled(bool group)
wxString getAttributeValue(const SCH_SYMBOL &, const wxString &aAttributeName)
bool ColIsItemNumber(int aCol)
bool ColIsQuantity(int aCol)
void updateDataStoreSymbolField(const SCH_SYMBOL &aSymbol, const wxString &aFieldName)
bool groupMatch(const SCH_REFERENCE &lhRef, const SCH_REFERENCE &rhRef)
wxGridCellAttr * m_urlEditor
BOM_PRESET GetBomSettings()
bool unitMatch(const SCH_REFERENCE &lhRef, const SCH_REFERENCE &rhRef)
bool ColIsReference(int aCol)
wxString GetExportValue(int aRow, int aCol, const wxString &refDelimiter, const wxString &refRangeDelimiter)
bool GetGroupingEnabled()
int GetNumberRows() override
void CollapseRow(int aRow)
wxString getFieldShownText(const SCH_REFERENCE &aRef, const wxString &aFieldName)
void RenameColumn(int aCol, const wxString &newName)
wxString Export(const BOM_FMT_PRESET &settings)
void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser)
std::vector< DATA_MODEL_COL > m_cols
void SetSorting(int aCol, bool ascending)
void ExpandCollapseRow(int aRow)
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
void SetFilter(const wxString &aFilter)
std::map< int, wxGridCellAttr * > m_colAttrs
static bool cmp(const DATA_MODEL_ROW &lhGroup, const DATA_MODEL_ROW &rhGroup, FIELDS_EDITOR_GRID_DATA_MODEL *dataModel, int sortCol, bool ascending)
static const wxString ITEM_NUMBER_VARIABLE
void SetIncludeExcludedFromBOM(bool include)
bool isAttribute(const wxString &aFieldName)
wxString GetValue(int aRow, int aCol) override
int GetDataWidth(int aCol)
void UpdateReferences(const SCH_REFERENCE_LIST &aRefs)
void ApplyData(SCH_COMMIT &aCommit)
void RemoveColumn(int aCol)
GROUP_TYPE GetRowFlags(int aRow)
const wxString & GetFilter()
std::map< KIID, std::map< wxString, wxString > > m_dataStore
static const wxString QUANTITY_VARIABLE
bool ColIsValue(int aCol)
void SetGroupColumn(int aCol, bool group)
void SetExcludeDNP(bool exclude)
void RemoveSymbol(const SCH_SYMBOL &aSymbol)
std::vector< BOM_FIELD > GetFieldsOrdered()
void SetValue(int aRow, int aCol, const wxString &aValue) override
bool ColIsAttribute(int aCol)
void SetColLabelValue(int aCol, const wxString &aLabel) override
void RemoveReferences(const SCH_REFERENCE_LIST &aRefs)
bool GetIncludeExcludedFromBOM()
void SetShowColumn(int aCol, bool show)
void setAttributeValue(SCH_SYMBOL &aSymbol, const wxString &aAttributeName, const wxString &aValue)
void AddReferences(const SCH_REFERENCE_LIST &aRefs)
These are loaded from Eeschema settings but then overwritten by the project settings.
SCHEMATIC_SETTINGS & Settings() const
wxString ConvertKIIDsToRefs(const wxString &aSource) const
wxString ConvertRefsToKIIDs(const wxString &aSource) const
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
void SetText(const wxString &aText) override
void SetPrivate(bool aPrivate)
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
bool Contains(const SCH_REFERENCE &aItem) const
Return true if aItem exists in this list.
iterator erase(iterator position)
static wxString Shorthand(std::vector< SCH_REFERENCE > aList, const wxString &refDelimiter, const wxString &refRangeDelimiter)
Return a shorthand string representing all the references in the list.
int FindRefByFullPath(const wxString &aFullPath) const
Search the list for a symbol with the given KIID path (as string).
void AddItem(const SCH_REFERENCE &aItem)
void RemoveItem(unsigned int aIndex)
Remove an item from the list of references.
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
wxString GetFullRef() const
Return reference name with unit altogether.
SCH_SYMBOL * GetSymbol() const
wxString GetRefNumber() const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool GetExcludedFromBOM() const
bool IsContainedWithin(const SCH_SHEET_PATH &aSheetPathToTest) const
Check if this path is contained inside aSheetPathToTest.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
bool GetExcludedFromBoard() const
bool GetExcludedFromBOM() const
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
bool GetDNP() const
Set or clear the 'Do Not Populate' flag.
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
bool GetExcludedFromSim() const override
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
bool IsGeneratedField(const wxString &aSource)
Returns true if the string is generated, e.g contains a single text var reference.
@ GROUP_COLLAPSED_DURING_SORT
KICOMMON_API wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
int ValueStringCompare(const wxString &strFWord, const wxString &strSWord)
Compare strings like the strcmp function but handle numbers and modifiers within the string text corr...
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
wxString refRangeDelimiter
std::vector< BOM_FIELD > fieldsOrdered
bool includeExcludedFromBOM
std::vector< SCH_REFERENCE > m_Refs
wxString GetCanonicalFieldName(FIELD_T aFieldType)
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
VECTOR2< int32_t > VECTOR2I