From 47ee2773d2036dc097fc8304c813de8eae3aae38 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 18 Apr 2017 22:43:40 +1000 Subject: [PATCH] Reworked field association - Allow duplicate components to access same field data --- eeschema/bom_table_model.cpp | 163 ++++++++++++++++++++++++++++------- eeschema/bom_table_model.h | 54 ++++++++++-- 2 files changed, 178 insertions(+), 39 deletions(-) diff --git a/eeschema/bom_table_model.cpp b/eeschema/bom_table_model.cpp index 5301e956e3..6e8a0f0e5e 100644 --- a/eeschema/bom_table_model.cpp +++ b/eeschema/bom_table_model.cpp @@ -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 ) { } @@ -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. */ 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_columnList = aColumnList; + m_fieldValues = aFieldValues; } /** @@ -471,10 +553,8 @@ bool BOM_TABLE_COMPONENT::AddUnit( SCH_REFERENCE aUnit ) break; } - SetFieldValue( column->Id(), value ); - - // Add the value to the fallback map - m_fallbackData[column->Id()] = value; + m_fieldValues->SetFieldValue( column->Id(), value ); + m_fieldValues->SetBackupValue( column->Id(), value ); } return true; @@ -489,16 +569,22 @@ bool BOM_TABLE_COMPONENT::AddUnit( SCH_REFERENCE aUnit ) */ wxString BOM_TABLE_COMPONENT::GetFieldValue( unsigned int aFieldId ) const { - auto search = m_fieldData.find( aFieldId ); + wxString value; - if( search != m_fieldData.end() ) - { - return search->second; - } - else + switch ( aFieldId ) { + case BOM_COL_ID_QUANTITY: 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 ) { - 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; } @@ -550,13 +636,7 @@ bool BOM_TABLE_COMPONENT::HasValueChanged( BOM_COLUMN* aField ) const return false; } - auto value = m_fieldData.find( 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; + return m_fieldValues->HasValueChanged( aField->Id() ); } /** @@ -634,17 +714,7 @@ void BOM_TABLE_COMPONENT::RevertFieldChanges() break; } - if( column && HasValueChanged( column ) ) - { - if( m_fallbackData.count( column->Id() ) > 0 ) - { - m_fieldData[column->Id()] = m_fallbackData[column->Id()]; - } - else - { - m_fieldData[column->Id()] = wxEmptyString; - } - } + m_fieldValues->RevertChanges( column->Id() ); } } @@ -931,6 +1001,7 @@ void BOM_TABLE_MODEL::SetComponents( SCH_REFERENCE_LIST aRefs ) // Group multi-unit components together m_components.clear(); + m_fieldValues.clear(); for( unsigned int ii=0; iiGetField( 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( values ) ); + } + + auto* newComponent = new BOM_TABLE_COMPONENT( nullptr, &ColumnList, values ); newComponent->AddUnit( ref ); m_components.push_back( std::unique_ptr( newComponent ) ); @@ -1090,6 +1184,11 @@ bool BOM_TABLE_MODEL::SetValue( } } + if( m_widget ) + { + m_widget->Update(); + } + return result; } diff --git a/eeschema/bom_table_model.h b/eeschema/bom_table_model.h index 8cf3898331..7b160bb424 100644 --- a/eeschema/bom_table_model.h +++ b/eeschema/bom_table_model.h @@ -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_COMPONENT; // Class for displaying a single component +// Map column IDs to field values (for quick lookup) +typedef std::map 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 * There are three types of rows: @@ -144,7 +184,7 @@ public: // List of units associated with this component std::vector 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 ); @@ -168,13 +208,9 @@ public: virtual BOM_TABLE_ROW* GetParent() const override { return m_parent; } protected: - // Initial data for reverting component values - std::map m_fallbackData; - - // Data as it is updated - std::map m_fieldData; - BOM_TABLE_GROUP* m_parent; + + BOM_FIELD_VALUES* m_fieldValues; }; /** @@ -189,8 +225,12 @@ class BOM_TABLE_MODEL : public wxDataViewModel protected: BOM_TABLE_MODEL(); + // Vector of unique component rows std::vector> m_components; + // Vector of field values mapped to field IDs + std::vector> m_fieldValues; + // BOM Preferences //! Group components based on values bool m_groupColumns = true;