Reworked field association
- Allow duplicate components to access same field data
This commit is contained in:
parent
d792e36151
commit
47ee2773d2
|
@ -53,6 +53,86 @@ static BOM_TABLE_ROW const* ItemToRow( wxDataViewItem aItem )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOM_FIELD_VALUES::BOM_FIELD_VALUES( wxString aRefDes ) : m_refDes( aRefDes )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current value for the provided field ID
|
||||||
|
*/
|
||||||
|
bool BOM_FIELD_VALUES::GetFieldValue( unsigned int aFieldId, wxString& aValue ) const
|
||||||
|
{
|
||||||
|
auto search = m_currentValues.find( aFieldId );
|
||||||
|
|
||||||
|
if( search == m_currentValues.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aValue = search->second;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the backup value for the provided field ID
|
||||||
|
*/
|
||||||
|
bool BOM_FIELD_VALUES::GetBackupValue( unsigned int aFieldId, wxString& aValue ) const
|
||||||
|
{
|
||||||
|
auto search = m_backupValues.find( aFieldId );
|
||||||
|
|
||||||
|
if( search == m_backupValues.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aValue = search->second;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value for the provided field ID
|
||||||
|
* Field value is set under any of the following conditions:
|
||||||
|
* - param aOverwrite is true
|
||||||
|
* - There is no current value
|
||||||
|
* - The current value is empty
|
||||||
|
*/
|
||||||
|
void BOM_FIELD_VALUES::SetFieldValue( unsigned int aFieldId, wxString aValue, bool aOverwrite )
|
||||||
|
{
|
||||||
|
if( aOverwrite || m_currentValues.count( aFieldId ) == 0 || m_currentValues[aFieldId].IsEmpty() )
|
||||||
|
{
|
||||||
|
m_currentValues[aFieldId] = aValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the backup value for the provided field ID
|
||||||
|
* If the backup value is already set, new value is ignored
|
||||||
|
*/
|
||||||
|
void BOM_FIELD_VALUES::SetBackupValue( unsigned int aFieldId, wxString aValue )
|
||||||
|
{
|
||||||
|
if( m_backupValues.count( aFieldId ) == 0 || m_backupValues[aFieldId].IsEmpty() )
|
||||||
|
{
|
||||||
|
m_backupValues[aFieldId] = aValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BOM_FIELD_VALUES::HasValueChanged( unsigned int aFieldId) const
|
||||||
|
{
|
||||||
|
wxString currentValue, backupValue;
|
||||||
|
|
||||||
|
GetFieldValue( aFieldId, currentValue );
|
||||||
|
GetBackupValue( aFieldId, backupValue );
|
||||||
|
|
||||||
|
return currentValue.Cmp( backupValue ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BOM_FIELD_VALUES::RevertChanges( unsigned int aFieldId )
|
||||||
|
{
|
||||||
|
wxString backupValue;
|
||||||
|
|
||||||
|
GetBackupValue( aFieldId, backupValue );
|
||||||
|
|
||||||
|
SetFieldValue( aFieldId, backupValue, true );
|
||||||
|
}
|
||||||
|
|
||||||
BOM_TABLE_ROW::BOM_TABLE_ROW() : m_columnList( nullptr )
|
BOM_TABLE_ROW::BOM_TABLE_ROW() : m_columnList( nullptr )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -416,10 +496,12 @@ int BOM_TABLE_GROUP::SortValues( const wxString& aFirst, const wxString& aSecond
|
||||||
* Each COMPONENT row is associated with a single component item.
|
* Each COMPONENT row is associated with a single component item.
|
||||||
*/
|
*/
|
||||||
BOM_TABLE_COMPONENT::BOM_TABLE_COMPONENT( BOM_TABLE_GROUP* aParent,
|
BOM_TABLE_COMPONENT::BOM_TABLE_COMPONENT( BOM_TABLE_GROUP* aParent,
|
||||||
BOM_COLUMN_LIST* aColumnList)
|
BOM_COLUMN_LIST* aColumnList,
|
||||||
|
BOM_FIELD_VALUES* aFieldValues )
|
||||||
{
|
{
|
||||||
m_parent = aParent;
|
m_parent = aParent;
|
||||||
m_columnList = aColumnList;
|
m_columnList = aColumnList;
|
||||||
|
m_fieldValues = aFieldValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -471,10 +553,8 @@ bool BOM_TABLE_COMPONENT::AddUnit( SCH_REFERENCE aUnit )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFieldValue( column->Id(), value );
|
m_fieldValues->SetFieldValue( column->Id(), value );
|
||||||
|
m_fieldValues->SetBackupValue( column->Id(), value );
|
||||||
// Add the value to the fallback map
|
|
||||||
m_fallbackData[column->Id()] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -489,16 +569,22 @@ bool BOM_TABLE_COMPONENT::AddUnit( SCH_REFERENCE aUnit )
|
||||||
*/
|
*/
|
||||||
wxString BOM_TABLE_COMPONENT::GetFieldValue( unsigned int aFieldId ) const
|
wxString BOM_TABLE_COMPONENT::GetFieldValue( unsigned int aFieldId ) const
|
||||||
{
|
{
|
||||||
auto search = m_fieldData.find( aFieldId );
|
wxString value;
|
||||||
|
|
||||||
if( search != m_fieldData.end() )
|
switch ( aFieldId )
|
||||||
{
|
|
||||||
return search->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case BOM_COL_ID_QUANTITY:
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
|
case BOM_COL_ID_REFERENCE:
|
||||||
|
return GetReference();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_fieldValues )
|
||||||
|
m_fieldValues->GetFieldValue( aFieldId, value );
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -509,9 +595,9 @@ wxString BOM_TABLE_COMPONENT::GetFieldValue( unsigned int aFieldId ) const
|
||||||
*/
|
*/
|
||||||
bool BOM_TABLE_COMPONENT::SetFieldValue( unsigned int aFieldId, const wxString aValue, bool aOverwrite )
|
bool BOM_TABLE_COMPONENT::SetFieldValue( unsigned int aFieldId, const wxString aValue, bool aOverwrite )
|
||||||
{
|
{
|
||||||
if( aOverwrite || m_fieldData.count( aFieldId ) == 0 || m_fieldData[aFieldId].IsEmpty() )
|
if( m_fieldValues )
|
||||||
{
|
{
|
||||||
m_fieldData[aFieldId] = aValue;
|
m_fieldValues->SetFieldValue( aFieldId, aValue, aOverwrite );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,13 +636,7 @@ bool BOM_TABLE_COMPONENT::HasValueChanged( BOM_COLUMN* aField ) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value = m_fieldData.find( aField->Id() );
|
return m_fieldValues->HasValueChanged( aField->Id() );
|
||||||
auto backup = m_fallbackData.find( aField->Id() );
|
|
||||||
|
|
||||||
wxString currentValue = value == m_fieldData.end() ? wxString() : value->second;
|
|
||||||
wxString backupValue = backup == m_fallbackData.end() ? wxString() : backup->second;
|
|
||||||
|
|
||||||
return currentValue.Cmp( backupValue ) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -634,17 +714,7 @@ void BOM_TABLE_COMPONENT::RevertFieldChanges()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( column && HasValueChanged( column ) )
|
m_fieldValues->RevertChanges( column->Id() );
|
||||||
{
|
|
||||||
if( m_fallbackData.count( column->Id() ) > 0 )
|
|
||||||
{
|
|
||||||
m_fieldData[column->Id()] = m_fallbackData[column->Id()];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_fieldData[column->Id()] = wxEmptyString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,6 +1001,7 @@ void BOM_TABLE_MODEL::SetComponents( SCH_REFERENCE_LIST aRefs )
|
||||||
|
|
||||||
// Group multi-unit components together
|
// Group multi-unit components together
|
||||||
m_components.clear();
|
m_components.clear();
|
||||||
|
m_fieldValues.clear();
|
||||||
|
|
||||||
for( unsigned int ii=0; ii<aRefs.GetCount(); ii++ )
|
for( unsigned int ii=0; ii<aRefs.GetCount(); ii++ )
|
||||||
{
|
{
|
||||||
|
@ -949,7 +1020,30 @@ void BOM_TABLE_MODEL::SetComponents( SCH_REFERENCE_LIST aRefs )
|
||||||
|
|
||||||
if( !found )
|
if( !found )
|
||||||
{
|
{
|
||||||
auto* newComponent = new BOM_TABLE_COMPONENT( nullptr, &ColumnList );
|
// Find the field:value map associated with this component
|
||||||
|
wxString refDes = ref.GetComp()->GetField( REFERENCE )->GetText();
|
||||||
|
|
||||||
|
bool dataFound = false;
|
||||||
|
|
||||||
|
BOM_FIELD_VALUES* values;
|
||||||
|
|
||||||
|
for( auto& data : m_fieldValues )
|
||||||
|
{
|
||||||
|
// Look for a match based on RefDes
|
||||||
|
if( data->GetReference().Cmp( refDes ) == 0 )
|
||||||
|
{
|
||||||
|
dataFound = true;
|
||||||
|
values = &*data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !dataFound )
|
||||||
|
{
|
||||||
|
values = new BOM_FIELD_VALUES( refDes );
|
||||||
|
m_fieldValues.push_back( std::unique_ptr<BOM_FIELD_VALUES>( values ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* newComponent = new BOM_TABLE_COMPONENT( nullptr, &ColumnList, values );
|
||||||
newComponent->AddUnit( ref );
|
newComponent->AddUnit( ref );
|
||||||
|
|
||||||
m_components.push_back( std::unique_ptr<BOM_TABLE_COMPONENT>( newComponent ) );
|
m_components.push_back( std::unique_ptr<BOM_TABLE_COMPONENT>( newComponent ) );
|
||||||
|
@ -1090,6 +1184,11 @@ bool BOM_TABLE_MODEL::SetValue(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_widget )
|
||||||
|
{
|
||||||
|
m_widget->Update();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,46 @@ class BOM_TABLE_ROW; // Base-class for table row data model
|
||||||
class BOM_TABLE_GROUP; // Class for displaying a group of components
|
class BOM_TABLE_GROUP; // Class for displaying a group of components
|
||||||
class BOM_TABLE_COMPONENT; // Class for displaying a single component
|
class BOM_TABLE_COMPONENT; // Class for displaying a single component
|
||||||
|
|
||||||
|
// Map column IDs to field values (for quick lookup)
|
||||||
|
typedef std::map<unsigned int, wxString> FIELD_VALUE_MAP;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The BOM_FIELD_VALUES class provides quick lookup of component values
|
||||||
|
* (based on Field ID)
|
||||||
|
* This is done for the following reasons:
|
||||||
|
* - Increase lookup speed for table values
|
||||||
|
* - Allow field values to be reverted to original values
|
||||||
|
* - Allow duplicate components to reference the same data
|
||||||
|
*/
|
||||||
|
class BOM_FIELD_VALUES
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BOM_FIELD_VALUES(wxString aRefDes);
|
||||||
|
|
||||||
|
bool GetFieldValue( unsigned int aFieldId, wxString& aValue ) const;
|
||||||
|
bool GetBackupValue( unsigned int aFieldId, wxString& aValue ) const;
|
||||||
|
|
||||||
|
void SetFieldValue( unsigned int aFieldId, wxString aValue, bool aOverwrite = false );
|
||||||
|
void SetBackupValue( unsigned int aFieldId, wxString aValue );
|
||||||
|
|
||||||
|
wxString GetReference() const { return m_refDes; }
|
||||||
|
|
||||||
|
bool HasValueChanged( unsigned int aFieldId ) const;
|
||||||
|
|
||||||
|
void RevertChanges( unsigned int aFieldId );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! The RefDes to which these values correspond
|
||||||
|
wxString m_refDes;
|
||||||
|
|
||||||
|
//! Current values for each column
|
||||||
|
FIELD_VALUE_MAP m_currentValues;
|
||||||
|
|
||||||
|
//! Backup values for each column
|
||||||
|
FIELD_VALUE_MAP m_backupValues;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual base class determining how a row is displayed
|
* Virtual base class determining how a row is displayed
|
||||||
* There are three types of rows:
|
* There are three types of rows:
|
||||||
|
@ -144,7 +184,7 @@ public:
|
||||||
// List of units associated with this component
|
// List of units associated with this component
|
||||||
std::vector<SCH_REFERENCE> Units;
|
std::vector<SCH_REFERENCE> Units;
|
||||||
|
|
||||||
BOM_TABLE_COMPONENT( BOM_TABLE_GROUP* aParent, BOM_COLUMN_LIST* aColumnList );
|
BOM_TABLE_COMPONENT( BOM_TABLE_GROUP* aParent, BOM_COLUMN_LIST* aColumnList, BOM_FIELD_VALUES* aValues );
|
||||||
|
|
||||||
bool AddUnit( SCH_REFERENCE aUnit );
|
bool AddUnit( SCH_REFERENCE aUnit );
|
||||||
|
|
||||||
|
@ -168,13 +208,9 @@ public:
|
||||||
virtual BOM_TABLE_ROW* GetParent() const override { return m_parent; }
|
virtual BOM_TABLE_ROW* GetParent() const override { return m_parent; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Initial data for reverting component values
|
|
||||||
std::map<unsigned int, wxString> m_fallbackData;
|
|
||||||
|
|
||||||
// Data as it is updated
|
|
||||||
std::map<unsigned int, wxString> m_fieldData;
|
|
||||||
|
|
||||||
BOM_TABLE_GROUP* m_parent;
|
BOM_TABLE_GROUP* m_parent;
|
||||||
|
|
||||||
|
BOM_FIELD_VALUES* m_fieldValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,8 +225,12 @@ class BOM_TABLE_MODEL : public wxDataViewModel
|
||||||
protected:
|
protected:
|
||||||
BOM_TABLE_MODEL();
|
BOM_TABLE_MODEL();
|
||||||
|
|
||||||
|
// Vector of unique component rows
|
||||||
std::vector<std::unique_ptr<BOM_TABLE_COMPONENT>> m_components;
|
std::vector<std::unique_ptr<BOM_TABLE_COMPONENT>> m_components;
|
||||||
|
|
||||||
|
// Vector of field values mapped to field IDs
|
||||||
|
std::vector<std::unique_ptr<BOM_FIELD_VALUES>> m_fieldValues;
|
||||||
|
|
||||||
// BOM Preferences
|
// BOM Preferences
|
||||||
//! Group components based on values
|
//! Group components based on values
|
||||||
bool m_groupColumns = true;
|
bool m_groupColumns = true;
|
||||||
|
|
Loading…
Reference in New Issue