41 default:
return wxT(
"unknown column" );
69 return wxT(
"bad wxWidgets!" );
86 wxFAIL_MSG( wxString::Format( wxT(
"column %d doesn't hold a bool value" ), aCol ) );
105 rowData.
label = aValue;
109 wxFAIL_MSG( wxString::Format( wxT(
"column %d doesn't hold a string value" ), aCol ) );
112 GetView()->Refresh();
128 wxFAIL_MSG( wxString::Format( wxT(
"column %d doesn't hold a bool value" ), aCol ) );
134 bool aShow,
bool aGroupBy )
138 if( wxGrid*
grid = GetView() )
140 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
141 grid->ProcessTableMessage( msg );
152 if( wxGrid*
grid = GetView() )
154 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
155 grid->ProcessTableMessage( msg );
162 wxCHECK( aRow >= 0 && aRow <
GetNumberRows(), wxEmptyString );
176 rowData.
name = aName;
191 m_cols.push_back( { aFieldName, aLabel, aAddedByUser,
false,
false } );
202 const wxString& aFieldName )
210 if( field->IsPrivate() )
253 node.key() = newName;
258 m_cols[aCol].m_fieldName = newName;
259 m_cols[aCol].m_label = newName;
265 for(
size_t i = 0; i <
m_cols.size(); i++ )
267 if(
m_cols[i].m_fieldName == aFieldName )
268 return static_cast<int>( i );
277 std::vector<BOM_FIELD> fields;
280 fields.push_back( { col.m_fieldName, col.m_label, col.m_show, col.m_group } );
288 size_t foundCount = 0;
290 for(
const wxString& newField : aNewOrder )
292 if( foundCount >=
m_cols.size() )
297 if( col.m_fieldName == newField )
299 std::swap(
m_cols[foundCount], col );
346 const wxString& refDelimiter,
347 const wxString& refRangeDelimiter,
349 bool listMixedValues )
351 std::vector<SCH_REFERENCE> references;
352 std::set<wxString> mixedValues;
359 references.push_back( ref );
378 else if( refFieldValue.Contains( wxT(
"${" ) ) )
382 std::function<bool( wxString* )> symbolResolver =
383 [&]( wxString* token ) ->
bool
388 refFieldValue =
ExpandTextVars( refFieldValue, & symbolResolver );
392 if( listMixedValues )
393 mixedValues.insert( refFieldValue );
394 else if( &ref == &
group.m_Refs.front() )
395 fieldValue = refFieldValue;
396 else if( fieldValue != refFieldValue )
401 if( listMixedValues )
403 fieldValue = wxEmptyString;
405 for(
const wxString& value : mixedValues )
407 if( value.IsEmpty() )
409 else if( fieldValue.IsEmpty() )
412 fieldValue +=
"," + value;
419 std::sort( references.begin(), references.end(),
422 wxString l_ref( l.GetRef() << l.GetRefNumber() );
423 wxString r_ref( r.GetRef() << r.GetRefNumber() );
424 return StrNumCmp( l_ref, r_ref, true ) < 0;
427 auto logicalEnd = std::unique( references.begin(), references.end(),
432 if( l.GetRefNumber() == wxT(
"?" ) )
435 wxString l_ref( l.GetRef() << l.GetRefNumber() );
436 wxString r_ref( r.GetRef() << r.GetRefNumber() );
437 return l_ref == r_ref;
440 references.erase( logicalEnd, references.end() );
446 fieldValue = wxString::Format( wxT(
"%d" ), (
int) references.size() );
448 fieldValue = wxString::Format( wxT(
"%d" ),
group.m_ItemNumber );
456 wxCHECK_RET( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ), wxS(
"Invalid column number" ) );
476 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
483 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
490 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
497 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
504 wxCHECK( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false );
515 if( lhGroup.
m_Refs.size() == 0 )
517 else if( rhGroup.
m_Refs.size() == 0 )
523 [ ascending ](
const auto a,
const auto b )
535 wxString lhs = dataModel->
GetValue( lhGroup, sortCol ).Trim(
true ).Trim(
false );
536 wxString rhs = dataModel->
GetValue( rhGroup, sortCol ).Trim(
true ).Trim(
false );
540 wxString lhRef = lhGroup.
m_Refs[0].GetRef() + lhGroup.
m_Refs[0].GetRefNumber();
541 wxString rhRef = rhGroup.
m_Refs[0].GetRef() + rhGroup.
m_Refs[0].GetRefNumber();
542 return local_cmp(
StrNumCmp( lhRef, rhRef,
true ), 0 );
559 std::sort( row.m_Refs.begin(), row.m_Refs.end(),
562 wxString lhs_ref( lhs.GetRef() << lhs.GetRefNumber() );
563 wxString rhs_ref( rhs.GetRef() << rhs.GetRefNumber() );
564 return StrNumCmp( lhs_ref, rhs_ref, true ) < 0;
571 return cmp( lhs, rhs, this, m_sortColumn, m_sortAscending );
578 row.m_ItemNumber = itemNumber++;
598 bool matchFound =
false;
605 if(
m_cols[refCol].m_group )
618 for(
size_t i = 0; i <
m_cols.size(); ++i )
621 if(
static_cast<int>( i ) == refCol )
652 wxString fieldName =
m_cols[i].m_fieldName;
665 const wxString& aFieldName )
672 return wxEmptyString;
684 std::function<bool( wxString* )> symbolResolver =
685 [&]( wxString* token ) ->
bool
693 return wxEmptyString;
699 return aFieldName == wxS(
"${DNP}" )
700 || aFieldName == wxS(
"${EXCLUDE_FROM_BOARD}" )
701 || aFieldName == wxS(
"${EXCLUDE_FROM_BOM}" )
702 || aFieldName == wxS(
"${EXCLUDE_FROM_SIM}" );
708 if( aAttributeName == wxS(
"${DNP}" ) )
709 return aSymbol.
GetDNP() ? wxS(
"1" ) : wxS(
"0" );
711 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
714 if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
717 if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
725 const wxString& aAttributeName,
726 const wxString& aValue )
728 bool attrChanged =
false;
729 bool newValue = aValue == wxS(
"1" );
731 if( aAttributeName == wxS(
"${DNP}" ) )
733 attrChanged = aSymbol.
GetDNP() != newValue;
734 aSymbol.
SetDNP( newValue );
736 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOARD}" ) )
741 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_BOM}" ) )
746 else if( aAttributeName == wxS(
"${EXCLUDE_FROM_SIM}" ) )
777 static_cast<WX_GRID*
>( GetView() )->CommitPendingChanges(
true );
779 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
780 GetView()->ProcessTableMessage( msg );
809 || (
m_scope == SCOPE::SCOPE_SHEET_RECURSIVE
815 bool matchFound =
false;
833 row.m_Refs.push_back( ref );
839 row.m_Refs.push_back( ref );
851 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
m_rows.size() );
852 GetView()->ProcessTableMessage( msg );
861 std::vector<DATA_MODEL_ROW> children;
865 bool matchFound =
false;
875 child.m_Refs.push_back( ref );
884 if( children.size() < 2 )
887 std::sort( children.begin(), children.end(),
890 return cmp( lhs, rhs, this, m_sortColumn, m_sortAscending );
894 m_rows.insert(
m_rows.begin() + aRow + 1, children.begin(), children.end() );
896 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, aRow, children.size() );
897 GetView()->ProcessTableMessage( msg );
903 auto firstChild =
m_rows.begin() + aRow + 1;
904 auto afterLastChild = firstChild;
907 while( afterLastChild !=
m_rows.end() && afterLastChild->m_Flag ==
CHILD_ITEM )
914 m_rows.erase( firstChild, afterLastChild );
916 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow + 1, deleted );
917 GetView()->ProcessTableMessage( msg );
934 for(
size_t i = 0; i <
m_rows.size(); ++i )
947 for(
size_t i = 0; i <
m_rows.size(); ++i )
957 bool symbolModified =
false;
958 std::unique_ptr<SCH_SYMBOL> symbolCopy;
969 symbolCopy = std::make_unique<SCH_SYMBOL>( *symbol );
973 for(
const auto& [srcName, srcValue] : fieldStore )
989 if( destField && destField->
IsPrivate() )
991 if( srcValue.IsEmpty() )
998 bool userAdded = ( col != -1 &&
m_cols[col].m_userAdded );
1001 bool createField = !destField && ( !srcValue.IsEmpty() || userAdded );
1009 destField->
SetVisible( srcTemplate->m_Visible );
1014 symbolModified =
true;
1026 wxString previousValue = destField->
GetText();
1030 if( !createField && ( previousValue != srcValue ) )
1031 symbolModified =
true;
1034 for(
int ii =
static_cast<int>( symbol->
GetFields().size() ) - 1; ii >= 0; ii-- )
1039 if( fieldStore.count( symbol->
GetFields()[ii].GetName() ) == 0 )
1042 symbolModified =
true;
1046 if( symbolModified && ( symbol != nextSymbol ) )
1050 if( symbol != nextSymbol )
1053 symbolCopy = std::make_unique<SCH_SYMBOL>( *nextSymbol );
1055 symbolCopy.reset(
nullptr );
1057 symbolModified =
false;
1078 for(
unsigned symbolRef = 0; symbolRef <
m_symbolsList.GetCount(); ++symbolRef )
1094 for(
size_t i = 0; i <
m_cols.size(); i++ )
1100 std::set<wxString> seen;
1101 std::vector<wxString> order;
1107 if( !field.
name || seen.count( field.
name ) )
1110 seen.insert( field.
name );
1111 order.emplace_back( field.
name );
1181 for(
size_t col = 0; col <
m_cols.size(); col++ )
1184 last_col =
static_cast<int>( col );
1188 if( last_col == -1 )
1192 [&]( wxString field,
bool last ) -> wxString
1196 field.Replace( wxS(
"\r" ), wxS(
"" ) );
1197 field.Replace( wxS(
"\n" ), wxS(
"" ) );
1202 field.Replace( wxS(
"\t" ), wxS(
"" ) );
1216 for(
size_t col = 0; col <
m_cols.size(); col++ )
1218 if( !
m_cols[col].m_show )
1221 out.Append( formatField(
m_cols[col].m_label, col ==
static_cast<size_t>( last_col ) ) );
1225 for(
size_t row = 0; row <
m_rows.size(); row++ )
1231 for(
size_t col = 0; col <
m_cols.size(); col++ )
1233 if( !
m_cols[col].m_show )
1237 out.Append( formatField(
GetExportValue(
static_cast<int>( row ),
static_cast<int>( col ),
1239 col ==
static_cast<size_t>( last_col ) ) );
1249 bool refListChanged =
false;
1262 if( !field.IsPrivate() )
1264 wxString
name = field.GetCanonicalName();
1271 refListChanged =
true;
1275 if( refListChanged )
1291 return ref.GetSymbol()->m_Uuid == aSymbol.m_Uuid;
1301 int index =
m_symbolsList.FindRefByFullPath( ref.GetFullPath() );
1308 if( ref.GetSymbol()->GetInstances().empty() )
1317 bool refListChanged =
false;
1330 refListChanged =
true;
1334 if( refListChanged )
COMMIT & Modified(EDA_ITEM *aItem, EDA_ITEM *aCopy, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetTextPos(const VECTOR2I &aPoint)
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
The flattened by hierarchy list of symbols.
void SetGroupingEnabled(bool group)
wxString getAttributeValue(const SCH_SYMBOL &, const wxString &aAttributeName)
bool ColIsItemNumber(int aCol)
int GetNumberCols() override
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)
FIELDS_EDITOR_GRID_DATA_MODEL(const SCH_REFERENCE_LIST &aSymbolsList, wxGridCellAttr *aURLEditor)
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)
bool setAttributeValue(SCH_SYMBOL &aSymbol, const wxString &aAttributeName, const wxString &aValue)
Set the attribute value.
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 ApplyData(SCH_COMMIT &aCommit, TEMPLATES &aTemplateFieldnames)
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 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 AddReferences(const SCH_REFERENCE_LIST &aRefs)
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 ...
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.
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
wxString GetFullRef(bool aIncludeUnit=true) const
Return reference name with unit altogether.
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.
void SetExcludedFromBoard(bool aExcludeFromBoard) override
Set or clear exclude from board netlist flag.
void SetDNP(bool aDNP) override
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
bool GetExcludedFromBoard() const override
void SetExcludedFromBOM(bool aExcludeFromBOM) override
Set or clear the exclude from schematic bill of materials flag.
bool GetDNP() const override
Set or clear the 'Do Not Populate' flag.
bool GetExcludedFromBOM() const override
bool GetExcludedFromSim() const override
const TEMPLATE_FIELDNAME * GetFieldName(const wxString &aName)
Search for aName in the template field name list.
void SetValueAsBool(int aRow, int aCol, bool aValue) override
wxString GetCanonicalFieldName(int aRow)
wxString GetColLabelValue(int aCol) override
std::vector< BOM_FIELD > m_fields
void SetValue(int aRow, int aCol, const wxString &aValue) override
int GetNumberRows() override
void AppendRow(const wxString &aFieldName, const wxString &aBOMName, bool aShow, bool aGroupBy)
bool GetValueAsBool(int aRow, int aCol) override
void SetCanonicalFieldName(int aRow, const wxString &aName)
wxString GetValue(int aRow, int aCol) override
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
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
#define DISPLAY_NAME_COLUMN
#define SHOW_FIELD_COLUMN
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
Hold a name of a symbol's field, field value, and default visibility.
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...