23#include <unordered_set>
118template <
typename ITEM_TYPE>
124 m_items.push_back( aFirstItem );
131 std::span<const ITEM_TYPE> items(
m_items );
157 virtual void AddColumn(
const wxString& aFieldName,
const wxString& aLabel,
bool aAddedByUser ) = 0;
246 virtual wxString
GetExportValue(
int aRow,
int aCol,
const wxString& aRefDelimiter,
247 const wxString& aRefRangeDelimiter ) = 0;
300 wxString
fieldVariant(
const wxString& aFieldName,
const wxString& aVariantName )
const;
363 std::map<KIID_PATH, std::map<wxString, FIELD_STORE_VALUE>>
m_dataStore;
377 void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
const wxRect& aRect,
int aRow,
int aCol,
378 bool isSelected )
override;
380 wxSize
GetBestSize( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
int aRow,
int aCol )
override;
382 wxGridCellRenderer*
Clone()
const override;
391template <
typename ITEM_TYPE>
406 void AddColumn(
const wxString& aFieldName,
const wxString& aLabel,
407 bool aAddedByUser )
override
415 m_cols.push_back( { aFieldName, aLabel, aAddedByUser,
false,
false } );
424 if( wxGrid*
grid = GetView() )
426 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
427 grid->ProcessTableMessage( msg );
437 wxCHECK_RET( aRow >= 0 && aRow <
static_cast<int>(
m_rows.size() ),
"Invalid Row Number" );
438 wxCHECK_RET( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
"Invalid Column Number" );
443 const wxString& fieldName =
m_cols[aCol].m_fieldName;
445 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
457 const wxString& fieldName =
m_cols[aCol].m_fieldName;
458 wxString variant = aVariantName.CmpNoCase(
GetDefaultVariantName() ) == 0 ? wxString() : aVariantName;
459 std::vector<wxString> values;
462 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
470 values.push_back( value );
484 wxCHECK_MSG( aRow >= 0 && aRow <
static_cast<int>(
m_rows.size() ),
false,
"Invalid Row Number" );
485 wxCHECK_MSG( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false,
"Invalid Column Number" );
487 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
505 wxCHECK_MSG( aRow >= 0 && aRow <
static_cast<int>(
m_rows.size() ),
false,
"Invalid Row Number" );
506 wxCHECK_MSG( aCol >= 0 && aCol <
static_cast<int>(
m_cols.size() ),
false,
"Invalid Column Number" );
508 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
524 wxCHECK( aRow >= 0 && aRow < (
int)
m_rows.size(), std::vector<KIID_PATH>() );
526 std::vector<KIID_PATH> keys;
528 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
537 wxCHECK( aRow >= 0 && aRow < (
int)
m_rows.size(), std::vector<ITEM_TYPE>() );
538 std::span<const ITEM_TYPE> items =
m_rows[aRow].GetCellItems();
539 return { items.begin(), items.end() };
550 wxCHECK_RET( aRow >= 0 && aRow <
static_cast<int>(
m_rows.size() ),
"Invalid Row Number" );
552 for(
const ITEM_TYPE& item :
m_rows[aRow].GetCellItems() )
564 std::vector<DATA_MODEL_ROW<ITEM_TYPE>> children;
566 std::span<const ITEM_TYPE> items(
m_rows[aRow].m_items );
568 for(
const ITEM_TYPE& ref : items.subspan( isParent ? 1 : 0 ) )
570 bool matchFound =
false;
580 child.m_items.push_back( ref );
586 children.emplace_back( ref, ROW_STATE::EXPANDED_CHILD );
589 if( children.empty() || ( !isParent && children.size() < 2 ) )
592 std::sort( children.begin(), children.end(),
596 return cmpRows( lhs, rhs, m_sortColumn, m_sortAscending );
599 m_rows[aRow].m_state = isParent ? ROW_STATE::PARENT_EXPANDED : ROW_STATE::GROUP_EXPANDED;
600 m_rows.insert(
m_rows.begin() + aRow + 1, children.begin(), children.end() );
604 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, aRow + 1, children.size() );
605 GetView()->ProcessTableMessage( msg );
612 auto firstChild =
m_rows.begin() + aRow + 1;
613 auto afterLastChild = firstChild;
616 while( afterLastChild !=
m_rows.end() && afterLastChild->m_state == ROW_STATE::EXPANDED_CHILD )
623 IsParentRow(
m_rows[aRow].m_state ) ? ROW_STATE::PARENT_COLLAPSED : ROW_STATE::GROUP_COLLAPSED;
624 m_rows.erase( firstChild, afterLastChild );
628 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow + 1, deleted );
629 GetView()->ProcessTableMessage( msg );
645 for(
size_t i = 0; i <
m_rows.size(); ++i )
651 : ROW_STATE::GROUP_COLLAPSED_DURING_SORT;
659 for(
size_t i = 0; i <
m_rows.size(); ++i )
661 if(
m_rows[i].m_state == ROW_STATE::GROUP_COLLAPSED_DURING_SORT
662 ||
m_rows[i].m_state == ROW_STATE::PARENT_COLLAPSED_DURING_SORT )
668 const wxString& refDelimiter = wxT(
", " ),
669 const wxString& refRangeDelimiter = wxT(
"-" ),
bool resolveVars =
false,
670 bool forExport =
false )
672 std::vector<ITEM_TYPE> items;
673 std::set<wxString> mixedValues;
677 std::span<const ITEM_TYPE> rowItems =
680 for(
const ITEM_TYPE& item : rowItems )
684 items.push_back( item );
688 wxString itemFieldValue;
697 itemFieldValue = wxS(
"1" );
722 mixedValues.insert( itemFieldValue );
723 else if( &item == &rowItems.front() )
724 fieldValue = itemFieldValue;
725 else if( fieldValue != itemFieldValue )
732 fieldValue = wxEmptyString;
734 for(
const wxString& value : mixedValues )
736 if( value.IsEmpty() )
738 else if( fieldValue.IsEmpty() )
741 fieldValue +=
"," + value;
748 std::sort( items.begin(), items.end(),
749 [
this](
const ITEM_TYPE& lhs,
const ITEM_TYPE& rhs ) ->
bool
751 return cmpRowItems( lhs, rhs );
754 auto logicalEnd = std::unique( items.begin(), items.end(),
755 [
this](
const ITEM_TYPE& lhs,
const ITEM_TYPE& rhs ) ->
bool
757 return unitMatch( lhs, rhs );
760 items.erase( logicalEnd, items.end() );
768 std::vector<wxString> itemIdentifiers;
770 for(
const ITEM_TYPE& item : items )
782 for(
const wxString& itemIdentifier : itemIdentifiers )
784 if( !fieldValue.IsEmpty() )
785 fieldValue += refDelimiter;
787 fieldValue += itemIdentifier;
792 fieldValue = wxString::Format( wxT(
"%d" ), (
int) items.size() );
794 fieldValue = wxString::Format( wxT(
"%d" ), aRow.
m_itemNumber );
802 wxCHECK( aRow >= 0 && aRow <
GetNumberRows(), wxEmptyString );
803 wxCHECK( aCol >= 0 && aCol <
GetNumberCols(), wxEmptyString );
814 const wxString& refRangeDelimiter )
override
847 return aMatcher.
Find( aReference.Lower() );
849 for(
size_t i = 0; i <
m_cols.size(); ++i )
878 if( aMatcher.
Find( value.Lower() ) )
897 const wxString& aVariantName )
const
920 int aSortCol,
bool aAscending )
925 else if( rhRow.
m_items.empty() )
931 [aAscending](
const auto a,
const auto b )
943 wxString lhs = this->
GetGroupedValue( lhRow, aSortCol, wxT(
", " ), wxT(
"-" ),
true )
946 wxString rhs = this->
GetGroupedValue( rhRow, aSortCol, wxT(
", " ), wxT(
"-" ),
true )
964 virtual bool cmpRowItems(
const ITEM_TYPE& lhItem,
const ITEM_TYPE& rhItem )
969 virtual bool unitMatch(
const ITEM_TYPE& lhItem,
const ITEM_TYPE& rhItem ) = 0;
971 bool groupMatch(
const ITEM_TYPE& lhItem,
const ITEM_TYPE& rhItem )
973 bool matchFound =
false;
975 for(
size_t i = 0; i <
m_cols.size(); ++i )
980 int col =
static_cast<int>( i );
996 const wxString& fieldName =
m_cols[i].m_fieldName;
1011 if( lhEffectiveValue != rhEffectiveValue )
1050 std::sort( row.m_items.begin() + (
IsParentRow( row.m_state ) ? 1 : 0 ), row.m_items.end(),
1051 [
this](
const ITEM_TYPE& lhs,
const ITEM_TYPE& rhs ) ->
bool
1053 return cmpRowItems( lhs, rhs );
1060 return cmpRows( lhs, rhs, m_sortColumn, m_sortAscending );
1068 row.m_itemNumber = itemNumber++;
1081 virtual bool getLiveFieldValue(
const ITEM_TYPE& aItem,
const wxString& aFieldName, wxString& aValue ) = 0;
1084 const wxString& aVariant, wxString& aValue )
1092 std::map<wxString, wxString>
getStoredFields(
const ITEM_TYPE& aItem,
const wxString& aVariant )
const
1094 std::map<wxString, wxString> fields;
1100 for(
const auto& [
name, field] : itemIt->second )
1102 auto valueIt = field.m_variants.find( aVariant );
1104 if( !field.m_present || valueIt == field.m_variants.end() )
1131 auto fieldIt = itemIt->second.find( aFieldName );
1133 if( fieldIt == itemIt->second.end() || !fieldIt->second.m_present )
1138 if( valueIt != fieldIt->second.m_variants.end() )
1139 aValue = valueIt->second.m_value;
1156 const auto& fields = itemIt->second;
1157 auto fieldIt = fields.find( *aToken );
1159 if( fieldIt == fields.end() && !aCaseSensitive )
1161 fieldIt = std::find_if( fields.begin(), fields.end(),
1162 [&](
const auto& aEntry )
1164 return aToken->IsSameAs( aEntry.first, false );
1171 const wxString&
name = fieldIt->first;
1200 const wxString& aValue )
1208 virtual void setCellValues(
int aRow,
int aCol,
const std::vector<wxString>& aValues )
1210 std::span<const ITEM_TYPE> items =
m_rows[aRow].GetCellItems();
1212 for(
size_t i = 0; i < items.size(); ++i )
1233 for(
auto& [variant, state] : field.
m_variants )
1234 state.m_value = state.m_baseline;
1245 wxString storedValue;
1249 return livePresent != storedPresent || liveValue != storedValue;
1260 bool aAllVariants =
false )
1269 bool allVariants = aAllVariants || field.
m_present != livePresent;
1271 for(
auto& [variant, state] : field.
m_variants )
1273 if( allVariants || variant == currentVariant )
1276 state.m_baseline = state.m_value;
1316 auto [fieldIt, newField] = fields.try_emplace( aFieldName );
1318 wxString variant =
fieldVariant( aFieldName, aVariantName );
1319 auto [valueIt, newVariant] = field.
m_variants.try_emplace( variant );
1342 if( !fields.contains( col.m_fieldName ) )
1350 bool livePresent = field.m_baselinePresent;
1351 bool liveChanged =
false;
1353 for(
auto& [variant, state] : field.m_variants )
1357 bool changed = livePresent != field.m_baselinePresent || live != state.m_baseline;
1360 if( changed || state.m_value == state.m_baseline )
1361 state.m_value = live;
1363 state.m_baseline = live;
1364 liveChanged |= changed;
1367 if( liveChanged || field.m_present == field.m_baselinePresent )
1368 field.m_present = livePresent;
1370 field.m_baselinePresent = livePresent;
1381 auto fieldIt = itemIt->second.find( aName );
1382 return fieldIt != itemIt->second.end() && !fieldIt->second.m_present && fieldIt->second.m_baselinePresent;
1387 std::set<wxString> variants;
1392 for(
const auto& [
name, field] : itemIt->second )
1394 for(
const auto& [variant, state] : field.m_variants )
1395 variants.insert( variant );
1410 wxString& aValue )
const
1435 std::vector<DATA_MODEL_ROW<ITEM_TYPE>>
m_rows;
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
virtual void CopyCellFromVariant(int aRow, int aCol, const wxString &aVariantName)=0
Copy each item's raw source value into the displayed variant, retaining staged edits.
void SetSelectionItems(const std::unordered_set< KIID_PATH > &aItems)
bool cellUsesResolvedTextRenderer(int aRow, int aCol)
const wxString & GetCurrentVariant() const
virtual bool fieldIsItemProperty(const wxString &aFieldName) const
void DeleteStoredVariant(const wxString &aName)
void SetVariantNames(const std::vector< wxString > &aVariantNames)
bool cellUsesUrlEditor(int aRow, int aCol)
~FIELDS_TABLE_DATA_MODEL_BASE() override
FIELDS_TABLE_DATA_MODEL_BASE()
virtual void SetCurrentVariant(const wxString &aVariantName)=0
Select the displayed variant, retaining un-applied edits in every variant.
BOM_FILTER_SCOPE GetFilterScope() const
virtual bool IsCellEdited(int aRow, int aCol)=0
void SetExcludeDNP(bool aExclude)
std::map< KIID_PATH, std::map< wxString, FIELD_STORE_VALUE > > m_dataStore
bool ColIsComputed(int aCol) const
void SetSorting(int aCol, bool aAscending)
int GetNumberCols() override
void MoveColumn(int aCol, int aNewPos)
wxString GetColFieldName(int aCol)
virtual void ClearCell(int aRow, int aCol)=0
bool ColIsValue(int aCol) const
bool IsEmptyCell(int aRow, int aCol) override
bool ColIsItemProperty(int aCol) const
void SetShowColumn(int aCol, bool aShow)
void SetIncludeExcludedFromBOM(bool aInclude)
bool IsRowEdited(int aRow)
Return true if any cell in the row has been edited.
wxGridCellAttr * applyFieldPresenceRenderer(wxGridCellAttr *aAttr, int aRow, int aCol)
bool CanClearCell(int aRow, int aCol)
std::vector< BOM_FIELD > GetFieldsOrdered()
bool ColIsAttribute(int aCol) const
static const wxString QUANTITY_VARIABLE
void applyResolvedTextRenderer(wxGridCellAttr *aAttr, bool aApplyTint)
static const wxString ITEM_NUMBER_VARIABLE
void commitPendingGridChanges()
virtual bool ColIsReadOnly(int aCol) const
virtual void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser)=0
bool HasUndoStateSerialization() const override
Optional identity-based serialization for the host dialog's Ctrl+Z/Ctrl+Y.
bool GetGroupColumn(int aCol)
wxString Export(const BOM_FMT_PRESET &aSettings)
wxGridCellRenderer * m_resolvedTextRenderer
bool ColIsReference(int aCol) const
virtual wxString GetExportValue(int aRow, int aCol, const wxString &aRefDelimiter, const wxString &aRefRangeDelimiter)=0
virtual bool ColIsItemIdentifier(int aCol) const
Reference for symbol/fields tables, lib_id for lib tables.
void SetColLabelValue(int aCol, const wxString &aLabel) override
wxGridCellAttr * cloneUrlEditorAttr()
void SetFilterScope(BOM_FILTER_SCOPE aScope)
bool ColIsQuantity(int aCol) const
virtual bool fieldIsAttribute(const wxString &aFieldName) const
BOM_PRESET GetBomSettings()
wxGridCellAttr * applyCellDecorations(wxGridCellAttr *aAttr, int aRow, int aCol)
virtual wxString getAttributeResolvedValue(const wxString &aFieldName, bool aValue) const
void ClearSelectionItems()
void SetFieldsOrder(const std::vector< wxString > &aNewOrder)
virtual void RevertRow(int aRow)=0
bool ColIsFootprint(int aCol) const
virtual bool IsCellReadOnly(int aRow, int aCol)
int GetFieldNameCol(const wxString &aFieldName) const
virtual wxString GetResolvedValue(int aRow, int aCol)=0
void RemoveColumn(int aCol)
wxString fieldVariant(const wxString &aFieldName, const wxString &aVariantName) const
bool GetIncludeExcludedFromBOM()
wxString SerializeUndoState() const override
void SetGroupingEnabled(bool aGroup)
std::unordered_set< KIID_PATH > m_selectionItems
Items included by the user selection scope.
int GetColDataWidth(int aCol)
bool ColIsItemNumber(int aCol) const
const wxString & GetFilter()
virtual bool fieldSupportsVariants(const wxString &aFieldName) const
std::vector< wxString > m_variantNames
Variant names for multi-variant DNP filtering.
virtual void ExpandCollapseRow(int aRow)=0
wxGridCellRenderer * m_stripedRenderer
std::vector< DATA_MODEL_COL > m_cols
bool GetGroupingEnabled()
bool CanCopyCellFromVariant(int aRow, int aCol)
const std::vector< wxString > & GetVariantNames() const
void RenameStoredVariant(const wxString &aOldName, const wxString &aNewName)
void RestoreUndoState(const wxString &aState) override
void RenameColumn(int aCol, const wxString &newName)
void SetGroupColumn(int aCol, bool aGroup)
void SetFilter(const wxString &aFilter)
wxString GetColLabelValue(int aCol) override
virtual std::vector< KIID_PATH > GetRowItemKeys(int aRow) const =0
Return the stable data-store keys of every item represented by a row.
bool GetShowColumn(int aCol)
void ApplyBomPreset(const BOM_PRESET &aPreset)
virtual void RebuildRows()=0
virtual bool IsCellClear(int aRow, int aCol)=0
BOM_FILTER_SCOPE m_filterScope
wxString m_currentVariant
Current variant name for highlighting.
bool HasRowLabelExpanders() const override
Show grouping controls in the row headers instead of row numbers.
The rest of the generic fields data model stuff, primarily around row functionality.
void CopyCellFromVariant(int aRow, int aCol, const wxString &aVariantName) override
Copy each item's raw source value into the displayed variant, retaining staged edits.
wxString GetGroupedValue(const DATA_MODEL_ROW< ITEM_TYPE > &aRow, int aCol, const wxString &refDelimiter=wxT(", "), const wxString &refRangeDelimiter=wxT("-"), bool resolveVars=false, bool forExport=false)
void RevertRow(int aRow) override
Go through and revert all the fields in the row to their live values from the item (symbol/footprint/...
void updateDataStoreItemFieldFromLive(const ITEM_TYPE &aItem, const wxString &aFieldName, bool aAllVariants=false)
Updates the data store with the current value of the field from the live item.
virtual wxString getItemIdentifier(const ITEM_TYPE &aItem) const =0
std::vector< ITEM_TYPE > GetRowReferences(int aRow) const
bool groupMatch(const ITEM_TYPE &lhItem, const ITEM_TYPE &rhItem)
void ensureStoredFieldPresent(const ITEM_TYPE &aItem, const wxString &aFieldName)
Makes sure a field is at least marked present-but-empty without changing its value if it has one alre...
void ExpandCollapseRow(int aRow) override
virtual std::vector< ITEM_TYPE > getAllItems() const =0
wxString GetExportValue(int aRow, int aCol, const wxString &refDelimiter, const wxString &refRangeDelimiter) override
void setStoredFieldValue(const ITEM_TYPE &aItem, const wxString &aFieldName, const wxString &aValue)
Creates or updates a field in the data store.
bool fieldIsModified(const ITEM_TYPE &aItem, const wxString &aFieldName)
Compares the live value of the field to the stored value in the data store.
void initializeDataStoreItemField(const ITEM_TYPE &aItem, const DATA_MODEL_COL &aCol)
Puts the live value of the field in the data store, correctly handling a missing field in the souce i...
void initializeDataStoreItem(const ITEM_TYPE &aItem)
Initializes every column in the data store for a newly added (or refreshed) item.
bool storedFieldIsRemoved(const ITEM_TYPE &aItem, const wxString &aName) const
void clearStoredField(const ITEM_TYPE &aItem, const wxString &aFieldName)
Clears a field, e.g.
virtual bool unitMatch(const ITEM_TYPE &lhItem, const ITEM_TYPE &rhItem)=0
bool attributeForcedOnBySheet(const ITEM_TYPE &aItem, const wxString &aAttributeName) const
Sheets can force all the symbols in them to have certain attributes on, like DNP.
FIELD_STORE_VALUE & storedField(const ITEM_TYPE &aItem, const wxString &aFieldName, const wxString &aVariantName)
bool cmpRows(const DATA_MODEL_ROW< ITEM_TYPE > &lhRow, const DATA_MODEL_ROW< ITEM_TYPE > &rhRow, int aSortCol, bool aAscending)
bool getStoredFieldValue(const ITEM_TYPE &aItem, const wxString &aFieldName, wxString &aValue) const
Gets the stored value of the field from the data store, not from the live item, e....
virtual bool getLiveFieldValue(const ITEM_TYPE &aItem, const wxString &aFieldName, wxString &aValue)=0
Gets the current value of the field from the live item, e.g.
virtual void getEffectiveFieldValue(const ITEM_TYPE &aItem, const wxString &aFieldName, wxString &aValue) const
bool IsCellEdited(int aRow, int aCol) override
Returns true if the cell has been modified from the live value in any item in the row (symbol/footpri...
std::vector< DATA_MODEL_ROW< ITEM_TYPE > > m_rows
FIELD_STORE_VALUE & storedField(const ITEM_TYPE &aItem, const wxString &aFieldName)
bool resolveStoredTextVar(const ITEM_TYPE &aItem, wxString *aToken, bool aCaseSensitive=false) const
Resolve an ordinary field token from the current variant's staged values.
bool IsCellReadOnly(int aRow, int aCol) override
std::map< wxString, wxString > getStoredFields(const ITEM_TYPE &aItem, const wxString &aVariant) const
Returns the edited, present fields belonging to a variant without creating entries.
void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser) override
void refreshDataStoreItem(const ITEM_TYPE &aItem)
wxString GetValue(int aRow, int aCol) override
std::vector< KIID_PATH > GetRowItemKeys(int aRow) const override
Return the stable data-store keys of every item represented by a row.
bool MatchesFilter(const ITEM_TYPE &aItem, const wxString &aReference, EDA_COMBINED_MATCHER &aMatcher)
bool IsCellClear(int aRow, int aCol) override
Returns true if the cell is not present in the data store for any item in the row,...
virtual bool attributeForcedOnBySheet(const ITEM_TYPE &aItem, const wxString &aAttributeName, const wxString &aVariantName) const
bool allRowItemsHaveAttributeForcedOnBySheet(const DATA_MODEL_ROW< ITEM_TYPE > &aRow, int aCol)
void CollapseRow(int aRow)
virtual KIID_PATH getDataStoreKey(const ITEM_TYPE &aItem) const =0
void ClearCell(int aRow, int aCol) override
Clears the field from the data store, rather than setting its value to an empty string.
ROW_STATE GetRowState(int aRow) const override
void acceptDataStoreItem(const ITEM_TYPE &aItem)
wxString GetResolvedValue(int aRow, int aCol) override
virtual void setCellValues(int aRow, int aCol, const std::vector< wxString > &aValues)
Write one value per item represented by the cell. Models may propagate shared storage.
void SetCurrentVariant(const wxString &aVariantName) override
Select the displayed variant, retaining un-applied edits in every variant.
virtual wxString getFieldResolvedLiveValue(const ITEM_TYPE &aItem, const wxString &aFieldName)=0
Explicitly bypasses the data store's field values and retries them from the item's current field valu...
virtual wxString resolveTextVars(const ITEM_TYPE &aItem, const wxString &aText)=0
virtual bool cmpRowItems(const ITEM_TYPE &lhItem, const ITEM_TYPE &rhItem)
int GetNumberRows() override
std::set< wxString > storedVariants(const ITEM_TYPE &aItem) const
virtual bool getLiveFieldValueForVariant(const ITEM_TYPE &aItem, const wxString &aFieldName, const wxString &aVariant, wxString &aValue)
GRID_CELL_RESOLVED_TEXT_RENDERER()
wxSize GetBestSize(wxGrid &aGrid, wxGridCellAttr &aAttr, wxDC &aDC, int aRow, int aCol) override
wxGridCellRenderer * Clone() const override
void Draw(wxGrid &aGrid, wxGridCellAttr &aAttr, wxDC &aDC, const wxRect &aRect, int aRow, int aCol, bool isSelected) override
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
bool IsGeneratedValue(const wxString &aValue)
Returns true if some of the string is generated, e.g contains a text var or expression.
bool IsGeneratedField(const wxString &aFieldName)
Returns true if the entire string is generated, e.g is a single text var reference.
Abstract pattern-matching tool and implementations.
const wxColour VARIANT_FIELD_OVERRIDE_DARK_YELLOW(80, 80, 40)
const wxColour VARIANT_FIELD_OVERRIDE_LIGHT_YELLOW(255, 255, 200)
const wxColour STRIPED_CLEARED_EMPTY_FIELD_LIGHT_GREEN(180, 220, 180)
const wxColour TEXT_VARIABLE_DARK_AMBER(80, 70, 30)
const wxColour CLEARED_FIELD_STRIPE_ON_DARK_LIGHT_RED(220, 180, 180)
const wxColour VARIANT_SYMBOL_OVERRIDE_LIGHT_BLUE(220, 235, 255)
const wxColour STRIPED_EDITED_EMPTY_FIELD_MUTED_GREEN(180, 200, 180)
const wxColour EDITED_EMPTY_FIELD_BRIGHT_GREEN(192, 255, 192)
const wxColour TEXT_VARIABLE_LIGHT_YELLOW(255, 252, 200)
const wxColour VARIANT_SYMBOL_OVERRIDE_DARK_BLUE(40, 60, 80)
const wxColour STRIPED_EDITED_NONEMPTY_FIELD_MUTED_RED(200, 180, 180)
const wxColour STRIPED_CLEARED_NONEMPTY_FIELD_LIGHT_RED(220, 180, 180)
const wxColour CLEARED_FIELD_STRIPE_ON_LIGHT_DARK_RED(100, 10, 10)
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
wxString FormatRefDesRanges(const std::vector< wxString > &aReferences, const wxString &aRefDelimiter, const wxString &aRefRangeDelimiter)
Format a sorted list of reference designators, shortening consecutive sequences of three or more refe...
Collection of utility functions for component reference designators (refdes)
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString GetDefaultVariantName()
wxString UnescapeString(const wxString &aSource)
int ValueStringCompare(const wxString &strFWord, const wxString &strSWord)
Compare strings like the strcmp function but handle numbers and modifiers within the string text corr...
The point of the data model classes is fundamentally to represent three things:
std::vector< LIB_SYMBOL * > m_items
DATA_MODEL_ROW(const ITEM_TYPE &aFirstItem, ROW_STATE aGroupingState)
std::span< const ITEM_TYPE > GetCellItems() const
Items displayed and edited by this row, excluding descendants of a real parent.
std::map< wxString, FIELD_VALUE_STATE > m_variants
Functions to provide common constants and other functions to assist in making a consistent UI.
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
bool IsRowCollapsed(ROW_STATE aState)
enum KICOMMON_API ROW_STATE
Used primarily by the fields tables to collapse multiple grouped symbols, etc.
bool IsParentRow(ROW_STATE aState)
bool IsRowExpanded(ROW_STATE aState)