ADDED: Dynamic field columns in symbol chooser
CHANGED: Symbol chooser search now considers custom symbol fields Visible columns can be controlled in database libraries. In standard KiCad libraries, we show columns for all custom fields for now. Customizable column visibility will be added in the future. Fixes https://gitlab.com/kicad/code/kicad/-/issues/11946
This commit is contained in:
parent
29c2151da5
commit
e294fe2074
|
@ -175,6 +175,8 @@ LIB_TREE_NODE_LIB_ID::LIB_TREE_NODE_LIB_ID( LIB_TREE_NODE* aParent, LIB_TREE_ITE
|
|||
m_Desc = aItem->GetDescription();
|
||||
m_Footprint = aItem->GetFootprint();
|
||||
|
||||
aItem->GetChooserFields( m_Fields );
|
||||
|
||||
m_MatchName = aItem->GetName();
|
||||
m_SearchText = aItem->GetSearchText();
|
||||
m_Normalized = false;
|
||||
|
@ -206,6 +208,8 @@ void LIB_TREE_NODE_LIB_ID::Update( LIB_TREE_ITEM* aItem )
|
|||
m_Desc = aItem->GetDescription();
|
||||
m_MatchName = aItem->GetName();
|
||||
|
||||
aItem->GetChooserFields( m_Fields );
|
||||
|
||||
m_SearchText = aItem->GetSearchText();
|
||||
m_Normalized = false;
|
||||
|
||||
|
|
|
@ -74,16 +74,16 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent,
|
|||
m_show_units( true ),
|
||||
m_preselect_unit( 0 ),
|
||||
m_freeze( 0 ),
|
||||
m_col_part( nullptr ),
|
||||
m_col_desc( nullptr ),
|
||||
m_widget( nullptr )
|
||||
{
|
||||
// Default column widths
|
||||
m_colWidths[NAME_COL] = 300;
|
||||
m_colWidths[DESC_COL] = 2000;
|
||||
// Default column widths. Do not translate these names.
|
||||
m_colWidths[ wxT( "Item" ) ] = 300;
|
||||
m_colWidths[ wxT( "Description" ) ] = 600;
|
||||
|
||||
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
|
||||
m_colWidths[NAME_COL] = cfg->m_LibTree.column_width;
|
||||
|
||||
for( const std::pair<const wxString, int>& pair : cfg->m_LibTree.column_widths )
|
||||
m_colWidths[pair.first] = pair.second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,7 +96,16 @@ void LIB_TREE_MODEL_ADAPTER::SaveColWidths()
|
|||
if( m_widget )
|
||||
{
|
||||
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
|
||||
cfg->m_LibTree.column_width = m_widget->GetColumn( NAME_COL )->GetWidth();
|
||||
|
||||
cfg->m_LibTree.columns.clear();
|
||||
cfg->m_LibTree.column_widths.clear();
|
||||
|
||||
// TODO(JE) ordering?
|
||||
for( const std::pair<const wxString, wxDataViewColumn*>& pair : m_colNameMap )
|
||||
{
|
||||
cfg->m_LibTree.columns.emplace_back( pair.first );
|
||||
cfg->m_LibTree.column_widths[pair.first] = pair.second->GetWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,30 +245,59 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
|||
|
||||
void LIB_TREE_MODEL_ADAPTER::AttachTo( wxDataViewCtrl* aDataViewCtrl )
|
||||
{
|
||||
wxString itemHead = _( "Item" );
|
||||
wxString descHead = _( "Description" );
|
||||
|
||||
// The extent of the text doesn't take into account the space on either side
|
||||
// in the header, so artificially pad it
|
||||
wxSize itemHeadMinWidth = KIUI::GetTextSize( itemHead + wxT( "MMM" ), aDataViewCtrl );
|
||||
wxSize descHeadMinWidth = KIUI::GetTextSize( descHead + wxT( "MMM" ), aDataViewCtrl );
|
||||
|
||||
// Ensure the part column is wider than the smallest allowable width
|
||||
if( m_colWidths[NAME_COL] < itemHeadMinWidth.x )
|
||||
m_colWidths[NAME_COL] = itemHeadMinWidth.x;
|
||||
|
||||
m_widget = aDataViewCtrl;
|
||||
aDataViewCtrl->SetIndent( kDataViewIndent );
|
||||
aDataViewCtrl->AssociateModel( this );
|
||||
aDataViewCtrl->ClearColumns();
|
||||
|
||||
m_col_part = aDataViewCtrl->AppendTextColumn( itemHead, NAME_COL, wxDATAVIEW_CELL_INERT,
|
||||
m_colWidths[NAME_COL] );
|
||||
m_col_desc = aDataViewCtrl->AppendTextColumn( descHead, DESC_COL, wxDATAVIEW_CELL_INERT,
|
||||
m_colWidths[DESC_COL] );
|
||||
// These two columns are always added; other columns may be added by specific libraries.
|
||||
// Do not use translated names here.
|
||||
doAddColumn( wxT( "Item" ) );
|
||||
|
||||
m_col_part->SetMinWidth( itemHeadMinWidth.x );
|
||||
m_col_desc->SetMinWidth( descHeadMinWidth.x );
|
||||
// TODO(JE) make Description optional
|
||||
doAddColumn( wxT( "Description" ) );
|
||||
|
||||
for( auto& it : m_colNameMap )
|
||||
{
|
||||
if( !it.second )
|
||||
doAddColumn( it.first, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader, bool aTranslate )
|
||||
{
|
||||
wxString translatedHeader = aTranslate ? wxGetTranslation( aHeader ) : aHeader;
|
||||
|
||||
// The extent of the text doesn't take into account the space on either side
|
||||
// in the header, so artificially pad it
|
||||
wxSize headerMinWidth = KIUI::GetTextSize( translatedHeader + wxT( "MMM" ), m_widget );
|
||||
|
||||
if( !m_colWidths.count( aHeader ) || m_colWidths[aHeader] < headerMinWidth.x )
|
||||
m_colWidths[aHeader] = headerMinWidth.x;
|
||||
|
||||
int index = m_columns.size();
|
||||
|
||||
wxDataViewColumn* ret = m_widget->AppendTextColumn( translatedHeader, index,
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
m_colWidths[aHeader] );
|
||||
ret->SetMinWidth( headerMinWidth.x );
|
||||
|
||||
m_columns.emplace_back( ret );
|
||||
m_colNameMap[aHeader] = ret;
|
||||
m_colIdxMap[m_columns.size() - 1] = aHeader;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::addColumnIfNecessary( const wxString& aHeader )
|
||||
{
|
||||
if( m_colNameMap.count( aHeader ) )
|
||||
return;
|
||||
|
||||
// Columns will be created later
|
||||
m_colNameMap[aHeader] = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -352,19 +390,46 @@ unsigned int LIB_TREE_MODEL_ADAPTER::GetChildren( const wxDataViewItem& aItem,
|
|||
|
||||
void LIB_TREE_MODEL_ADAPTER::FinishTreeInitialization()
|
||||
{
|
||||
m_col_part->SetWidth( m_colWidths[NAME_COL] );
|
||||
m_col_desc->SetWidth( m_colWidths[DESC_COL] );
|
||||
wxDataViewColumn* col = nullptr;
|
||||
size_t idx = 0;
|
||||
int totalWidth = 0;
|
||||
wxString header;
|
||||
|
||||
for( ; idx < m_columns.size() - 1; idx++ )
|
||||
{
|
||||
col = m_columns[idx];
|
||||
header = col->GetTitle();
|
||||
|
||||
wxASSERT( m_colWidths.count( header ) );
|
||||
|
||||
col->SetWidth( m_colWidths[header] );
|
||||
totalWidth += col->GetWidth();
|
||||
}
|
||||
|
||||
int remainingWidth = m_widget->GetSize().x - totalWidth;
|
||||
header = m_columns[idx]->GetTitle();
|
||||
|
||||
m_columns[idx]->SetWidth( std::max( m_colWidths[header], remainingWidth ) );
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::OnSize( wxSizeEvent& aEvent )
|
||||
{
|
||||
// On GTK, this value in not immediately available, so don't
|
||||
// set it to zero just because we haven't fully initialized
|
||||
if( m_col_part->GetWidth() > 0 )
|
||||
m_colWidths[NAME_COL] = m_col_part->GetWidth();
|
||||
for( auto& it : m_colNameMap )
|
||||
{
|
||||
if( it.second == m_columns[0] )
|
||||
{
|
||||
// On GTK, this value in not immediately available, so don't
|
||||
// set it to zero just because we haven't fully initialized
|
||||
if( it.second->GetWidth() > 0 )
|
||||
m_colWidths[it.first] = it.second->GetWidth();
|
||||
|
||||
m_col_desc->SetWidth( m_colWidths[DESC_COL] );
|
||||
continue;
|
||||
}
|
||||
|
||||
wxASSERT( m_colWidths.count( it.first ) );
|
||||
it.second->SetWidth( m_colWidths[it.first] );
|
||||
}
|
||||
|
||||
// Mandatory in any wxSizeEvent handler:
|
||||
aEvent.Skip();
|
||||
|
@ -378,22 +443,40 @@ void LIB_TREE_MODEL_ADAPTER::RefreshTree()
|
|||
// user's scroll position (which re-attaching or deleting/re-inserting columns does).
|
||||
static int walk = 1;
|
||||
|
||||
int partWidth = m_col_part->GetWidth();
|
||||
int descWidth = m_col_desc->GetWidth();
|
||||
std::vector<int> widths;
|
||||
|
||||
for( const wxDataViewColumn* col : m_columns )
|
||||
widths.emplace_back( col->GetWidth() );
|
||||
|
||||
wxASSERT( widths.size() );
|
||||
|
||||
// Only use the widths read back if they are non-zero.
|
||||
// GTK returns the displayed width of the column, which is not calculated immediately
|
||||
if( descWidth > 0 )
|
||||
if( widths[0] > 0 )
|
||||
{
|
||||
m_colWidths[NAME_COL] = partWidth;
|
||||
m_colWidths[DESC_COL] = descWidth;
|
||||
size_t i = 0;
|
||||
|
||||
for( auto& it : m_colNameMap )
|
||||
m_colWidths[it.first] = widths[i++];
|
||||
}
|
||||
|
||||
m_colWidths[NAME_COL] += walk;
|
||||
m_colWidths[DESC_COL] -= walk;
|
||||
auto colIt = m_colWidths.begin();
|
||||
|
||||
colIt->second += walk;
|
||||
colIt++;
|
||||
|
||||
if( colIt != m_colWidths.end() )
|
||||
colIt->second -= walk;
|
||||
|
||||
for( auto& it : m_colNameMap )
|
||||
{
|
||||
if( it.second == m_columns[0] )
|
||||
continue;
|
||||
|
||||
wxASSERT( m_colWidths.count( it.first ) );
|
||||
it.second->SetWidth( m_colWidths[it.first] );
|
||||
}
|
||||
|
||||
m_col_part->SetWidth( m_colWidths[NAME_COL] );
|
||||
m_col_desc->SetWidth( m_colWidths[DESC_COL] );
|
||||
walk = -walk;
|
||||
}
|
||||
|
||||
|
@ -443,13 +526,25 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
|||
|
||||
switch( aCol )
|
||||
{
|
||||
default: // column == -1 is used for default Compare function
|
||||
case 0:
|
||||
case NAME_COL:
|
||||
aVariant = UnescapeString( node->m_Name );
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case DESC_COL:
|
||||
aVariant = node->m_Desc;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
wxCHECK_RET( m_colIdxMap.count( aCol ), wxT( "Invalid column in LIB_TREE_MODEL_ADAPTER" ) );
|
||||
|
||||
if( node->m_Fields.count( m_colIdxMap.at( aCol ) ) )
|
||||
aVariant = node->m_Fields[m_colIdxMap.at( aCol )];
|
||||
else
|
||||
aVariant = wxEmptyString;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
|||
m_appSettingsSchemaVersion( aSchemaVersion )
|
||||
{
|
||||
// Make Coverity happy:
|
||||
m_LibTree.column_width = 300;
|
||||
m_Graphics.canvas_type = EDA_DRAW_PANEL_GAL::GAL_FALLBACK;
|
||||
|
||||
// Build parameters list:
|
||||
|
@ -79,8 +78,32 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
|||
m_params.emplace_back( new PARAM<int>( "color_picker.default_tab",
|
||||
&m_ColorPicker.default_tab, 0 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "lib_tree.column_width",
|
||||
&m_LibTree.column_width, 300 ) );
|
||||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "lib_tree.column_widths",
|
||||
[&]() -> nlohmann::json
|
||||
{
|
||||
nlohmann::json ret = {};
|
||||
|
||||
for( const std::pair<const wxString, int>& pair : m_LibTree.column_widths )
|
||||
ret[std::string( pair.first.ToUTF8() )] = pair.second;
|
||||
|
||||
return ret;
|
||||
},
|
||||
[&]( const nlohmann::json& aJson )
|
||||
{
|
||||
if( !aJson.is_object() )
|
||||
return;
|
||||
|
||||
m_LibTree.column_widths.clear();
|
||||
|
||||
for( const auto& entry : aJson.items() )
|
||||
{
|
||||
if( !entry.value().is_number_integer() )
|
||||
continue;
|
||||
|
||||
m_LibTree.column_widths[ entry.key() ] = entry.value().get<int>();
|
||||
}
|
||||
},
|
||||
{} ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "printing.background",
|
||||
&m_Printing.background, false ) );
|
||||
|
@ -363,3 +386,17 @@ const std::vector<wxString> APP_SETTINGS_BASE::DefaultGridSizeList() const
|
|||
"0.025 mm",
|
||||
"0.01 mm" };
|
||||
}
|
||||
|
||||
|
||||
bool APP_SETTINGS_BASE::migrateLibTreeWidth()
|
||||
{
|
||||
// We used to store only the width of the first column, because there were only
|
||||
// two possible columns.
|
||||
if( std::optional<int> optWidth = Get<int>( "lib_tree.column_width" ) )
|
||||
{
|
||||
Set<nlohmann::json>( "lib_tree.column_widths", { { "Item", *optWidth } } );
|
||||
At( "lib_tree" ).erase( "column_width" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
using namespace T_BOMCFG_T; // for the BOM_CFG_PARSER parser and its keywords
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int eeschemaSchemaVersion = 2;
|
||||
const int eeschemaSchemaVersion = 3;
|
||||
|
||||
/// Default value for bom.plugins
|
||||
const nlohmann::json defaultBomPlugins =
|
||||
|
@ -475,6 +475,13 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
|
|||
|
||||
return true;
|
||||
} );
|
||||
|
||||
registerMigration( 2, 3,
|
||||
[&]() -> bool
|
||||
{
|
||||
// This is actually a migration for APP_SETTINGS_BASE::m_LibTree
|
||||
return migrateLibTreeWidth();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ LIB_FIELD& LIB_FIELD::operator=( const LIB_FIELD& field )
|
|||
m_autoAdded = field.m_autoAdded;
|
||||
m_showName = field.m_showName;
|
||||
m_allowAutoPlace = field.m_allowAutoPlace;
|
||||
m_showInChooser = field.m_showInChooser;
|
||||
|
||||
SetText( field.GetText() );
|
||||
SetAttributes( field );
|
||||
|
@ -105,6 +106,7 @@ void LIB_FIELD::Init( int aId )
|
|||
m_autoAdded = false;
|
||||
m_showName = false;
|
||||
m_allowAutoPlace = true;
|
||||
m_showInChooser = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,6 +201,7 @@ void LIB_FIELD::Copy( LIB_FIELD* aTarget ) const
|
|||
aTarget->m_name = m_name;
|
||||
aTarget->m_showName = m_showName;
|
||||
aTarget->m_allowAutoPlace = m_allowAutoPlace;
|
||||
aTarget->m_showInChooser = m_showInChooser;
|
||||
|
||||
aTarget->CopyText( *this );
|
||||
aTarget->SetAttributes( *this );
|
||||
|
|
|
@ -184,6 +184,9 @@ public:
|
|||
bool CanAutoplace() const { return m_allowAutoPlace; }
|
||||
void SetCanAutoplace( bool aCanPlace ) { m_allowAutoPlace = aCanPlace; }
|
||||
|
||||
bool ShowInChooser() const { return m_showInChooser; }
|
||||
void SetShowInChooser( bool aShow = true ) { m_showInChooser = aShow; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -223,6 +226,7 @@ private:
|
|||
bool m_autoAdded; ///< Was this field automatically added to a LIB_SYMBOL?
|
||||
bool m_showName; ///< Render the field's name in addition to its value
|
||||
bool m_allowAutoPlace; ///< This field can be autoplaced when converted to a SCH_FIELD
|
||||
bool m_showInChooser; ///< This field is available as a data column for the chooser
|
||||
};
|
||||
|
||||
#endif // CLASS_LIBENTRY_FIELDS_H
|
||||
|
|
|
@ -59,10 +59,29 @@ wxString LIB_SYMBOL::GetSearchText()
|
|||
text += discount + footprint;
|
||||
}
|
||||
|
||||
// TODO(JE) rework this later so we can highlight matches in their column
|
||||
std::map<wxString, wxString> fields;
|
||||
GetChooserFields( fields );
|
||||
|
||||
for( const auto& it : fields )
|
||||
text += discount + it.second;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
void LIB_SYMBOL::GetChooserFields( std::map<wxString , wxString>& aColumnMap )
|
||||
{
|
||||
for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
|
||||
{
|
||||
LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
|
||||
|
||||
if( field->ShowInChooser() )
|
||||
aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 )
|
||||
{
|
||||
return aItem1.GetName() < aItem2.GetName();
|
||||
|
|
|
@ -174,7 +174,9 @@ public:
|
|||
return GetFootprintField().GetText();
|
||||
}
|
||||
|
||||
/**
|
||||
void GetChooserFields( std::map<wxString , wxString>& aColumnMap ) override;
|
||||
|
||||
/**
|
||||
* For symbols derived from other symbols, IsRoot() indicates no derivation.
|
||||
*/
|
||||
bool IsRoot() const override { return m_parent.use_count() == 0; }
|
||||
|
|
|
@ -462,6 +462,34 @@ public:
|
|||
*/
|
||||
virtual void GetSubLibraryNames( std::vector<wxString>& aNames ) {}
|
||||
|
||||
/**
|
||||
* Retrieves a list of (custom) field names that are present on symbols in this library.
|
||||
* The plugin is responsible for guaranteeing that this list contains the set of unique
|
||||
* custom field names present on any symbols contained in the library.
|
||||
*
|
||||
* The required KiCad fields are not included in this list.
|
||||
*
|
||||
* @param aNames will be filled with any custom fields present in this library.
|
||||
*/
|
||||
virtual void GetAvailableSymbolFields( std::vector<wxString>& aNames ) {}
|
||||
|
||||
/**
|
||||
* Retrieves a list of (custom) field names that should be shown by default for this library
|
||||
* in the symbol chooser. This list should be a subset of the result returned by
|
||||
* GetAvailableSymbolFields().
|
||||
*
|
||||
* The preference for which fields to hide and show for a given library is stored on a
|
||||
* per-library basis in a user's preferences (or in the project local settings for a project-
|
||||
* local library). The set of fields returned by GetDefaultSymbolFields() will be used if this
|
||||
* preference is missing.
|
||||
*
|
||||
* @param aNames will be filled with the custom field names that should be shown by default
|
||||
*/
|
||||
virtual void GetDefaultSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
return GetAvailableSymbolFields( aNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the first line in @a aFileName begins with the expected header.
|
||||
*
|
||||
|
|
|
@ -153,6 +153,19 @@ void SCH_DATABASE_PLUGIN::GetSubLibraryNames( std::vector<wxString>& aNames )
|
|||
}
|
||||
|
||||
|
||||
void SCH_DATABASE_PLUGIN::GetAvailableSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
std::copy( m_customFields.begin(), m_customFields.end(), std::back_inserter( aNames ) );
|
||||
}
|
||||
|
||||
|
||||
void SCH_DATABASE_PLUGIN::GetDefaultSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
std::copy( m_defaultShownFields.begin(), m_defaultShownFields.end(),
|
||||
std::back_inserter( aNames ) );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_DATABASE_PLUGIN::CheckHeader( const wxString& aFileName )
|
||||
{
|
||||
// TODO: Implement this sometime; but CheckHeader isn't even called...
|
||||
|
@ -352,6 +365,11 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
|
|||
field->SetNameShown( mapping.show_name );
|
||||
|
||||
symbol->AddField( field );
|
||||
|
||||
m_customFields.insert( mapping.name );
|
||||
|
||||
if( mapping.visible_in_chooser )
|
||||
m_defaultShownFields.insert( mapping.name );
|
||||
}
|
||||
|
||||
return symbol;
|
||||
|
|
|
@ -77,6 +77,10 @@ public:
|
|||
|
||||
void GetSubLibraryNames( std::vector<wxString>& aNames ) override;
|
||||
|
||||
void GetAvailableSymbolFields( std::vector<wxString>& aNames ) override;
|
||||
|
||||
void GetDefaultSymbolFields( std::vector<wxString>& aNames ) override;
|
||||
|
||||
bool CheckHeader( const wxString& aFileName ) override;
|
||||
|
||||
// Database libraries can never be written using the symbol editing API
|
||||
|
@ -105,6 +109,10 @@ private:
|
|||
|
||||
std::unique_ptr<DATABASE_CONNECTION> m_conn;
|
||||
|
||||
std::set<wxString> m_customFields;
|
||||
|
||||
std::set<wxString> m_defaultShownFields;
|
||||
|
||||
};
|
||||
|
||||
#endif //KICAD_SCH_DATABASE_PLUGIN_H
|
||||
|
|
|
@ -1433,6 +1433,41 @@ bool SCH_SEXPR_PLUGIN::IsSymbolLibWritable( const wxString& aLibraryPath )
|
|||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PLUGIN::GetAvailableSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
if( !m_cache )
|
||||
return;
|
||||
|
||||
const LIB_SYMBOL_MAP& symbols = m_cache->m_symbols;
|
||||
|
||||
std::set<wxString> fieldNames;
|
||||
|
||||
for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
|
||||
{
|
||||
std::vector<LIB_FIELD*> fields;
|
||||
it->second->GetFields( fields );
|
||||
|
||||
for( LIB_FIELD* field : fields )
|
||||
{
|
||||
if( field->IsMandatory() )
|
||||
continue;
|
||||
|
||||
// TODO(JE): enable configurability of this outside database libraries?
|
||||
// if( field->ShowInChooser() )
|
||||
fieldNames.insert( field->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
std::copy( fieldNames.begin(), fieldNames.end(), std::back_inserter( aNames ) );
|
||||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PLUGIN::GetDefaultSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
GetAvailableSymbolFields( aNames );
|
||||
}
|
||||
|
||||
|
||||
LIB_SYMBOL* SCH_SEXPR_PLUGIN::ParseLibSymbol( LINE_READER& aReader, int aFileVersion )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
|
|
@ -133,6 +133,9 @@ public:
|
|||
bool CheckHeader( const wxString& aFileName ) override;
|
||||
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
|
||||
|
||||
void GetAvailableSymbolFields( std::vector<wxString>& aNames ) override;
|
||||
void GetDefaultSymbolFields( std::vector<wxString>& aNames ) override;
|
||||
|
||||
const wxString& GetError() const override { return m_error; }
|
||||
|
||||
static LIB_SYMBOL* ParseLibSymbol( LINE_READER& aReader,
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int libeditSchemaVersion = 0;
|
||||
const int libeditSchemaVersion = 1;
|
||||
|
||||
|
||||
SYMBOL_EDITOR_SETTINGS::SYMBOL_EDITOR_SETTINGS() :
|
||||
|
@ -81,6 +81,13 @@ SYMBOL_EDITOR_SETTINGS::SYMBOL_EDITOR_SETTINGS() :
|
|||
|
||||
m_params.emplace_back( new PARAM<bool>( "use_eeschema_color_settings",
|
||||
&m_UseEeschemaColorSettings, true ) );
|
||||
|
||||
registerMigration( 0, 1,
|
||||
[&]() -> bool
|
||||
{
|
||||
// This is actually a migration for APP_SETTINGS_BASE::m_LibTree
|
||||
return migrateLibTreeWidth();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,6 +84,24 @@ public:
|
|||
|
||||
void GetSubLibraryNames( std::vector<wxString>& aNames ) const;
|
||||
|
||||
/**
|
||||
* @see SCH_PLUGIN::GetAvailableSymbolFields
|
||||
*/
|
||||
void GetAvailableSymbolFields( std::vector<wxString>& aNames ) const
|
||||
{
|
||||
if( plugin )
|
||||
plugin->GetAvailableSymbolFields( aNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SCH_PLUGIN::GetDefaultSymbolFields
|
||||
*/
|
||||
void GetDefaultSymbolFields( std::vector<wxString>& aNames ) const
|
||||
{
|
||||
if( plugin )
|
||||
plugin->GetDefaultSymbolFields( aNames );
|
||||
}
|
||||
|
||||
protected:
|
||||
SYMBOL_LIB_TABLE_ROW( const SYMBOL_LIB_TABLE_ROW& aRow ) :
|
||||
LIB_TABLE_ROW( aRow ),
|
||||
|
|
|
@ -136,6 +136,12 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
|
|||
if( !row->GetIsVisible() )
|
||||
continue;
|
||||
|
||||
std::vector<wxString> additionalColumns;
|
||||
row->GetAvailableSymbolFields( additionalColumns );
|
||||
|
||||
for( const wxString& column : additionalColumns )
|
||||
addColumnIfNecessary( column );
|
||||
|
||||
if( row->SupportsSubLibraries() )
|
||||
{
|
||||
std::vector<wxString> subLibraries;
|
||||
|
@ -248,6 +254,21 @@ void SYMBOL_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem co
|
|||
case DESC_COL:
|
||||
aVariant = node->m_Desc;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if( m_colIdxMap.count( aCol ) )
|
||||
{
|
||||
const wxString& key = m_colIdxMap.at( aCol );
|
||||
|
||||
if( node->m_Fields.count( key ) )
|
||||
aVariant = node->m_Fields.at( key );
|
||||
else
|
||||
aVariant = wxEmptyString;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef LIB_TREE_ITEM_H
|
||||
#define LIB_TREE_ITEM_H
|
||||
|
||||
#include <map>
|
||||
#include <lib_id.h>
|
||||
#include <import_export.h>
|
||||
|
||||
|
@ -46,9 +47,14 @@ public:
|
|||
|
||||
virtual wxString GetName() const = 0;
|
||||
virtual wxString GetLibNickname() const = 0;
|
||||
|
||||
virtual wxString GetDescription() = 0;
|
||||
|
||||
/**
|
||||
* Retrieves a key/value map of the fields on this item that should be exposed to the library
|
||||
* browser/chooser for displaying in columns, searching, etc
|
||||
*/
|
||||
virtual void GetChooserFields( std::map<wxString , wxString>& aColumnMap ) {}
|
||||
|
||||
virtual wxString GetSearchText() { return wxEmptyString; }
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define LIB_TREE_MODEL_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <wx/string.h>
|
||||
#include <lib_tree_item.h>
|
||||
|
@ -135,6 +136,8 @@ public:
|
|||
wxString m_SearchText; // Descriptive text to search
|
||||
bool m_Normalized; // Support for lazy normalization.
|
||||
|
||||
/// @see LIB_TREE_ITEMS::GetChooserFields
|
||||
std::map<wxString, wxString> m_Fields;
|
||||
|
||||
LIB_ID m_LibId; // LIB_ID determined by the parent library nickname and alias name.
|
||||
int m_Unit; // Actual unit, or zero
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <vector>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* Adapter class in the symbol selector Model-View-Adapter (mediated MVC)
|
||||
|
@ -123,15 +124,16 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* This enum defines the order of the columns in the tree view
|
||||
* This enum defines the order of the default columns in the tree view
|
||||
*/
|
||||
enum TREE_COLS
|
||||
{
|
||||
NAME_COL = 0, ///< Library or library item name column
|
||||
DESC_COL, ///< Library or library description column
|
||||
NUM_COLS ///< The number of tree columns
|
||||
NUM_COLS ///< The number of default tree columns
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Save the column widths to the config file. This requires the tree view to still be
|
||||
* valid.
|
||||
|
@ -179,6 +181,10 @@ public:
|
|||
const std::vector<LIB_TREE_ITEM*>& aItemList,
|
||||
bool pinned, bool presorted );
|
||||
|
||||
void AddColumn( const wxString& aHeader )
|
||||
{
|
||||
doAddColumn( aHeader, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the tree and assign ranks after adding libraries.
|
||||
|
@ -328,7 +334,7 @@ protected:
|
|||
*/
|
||||
wxDataViewItem GetParent( const wxDataViewItem& aItem ) const override;
|
||||
|
||||
unsigned int GetColumnCount() const override { return NUM_COLS; }
|
||||
unsigned int GetColumnCount() const override { return m_columns.size(); }
|
||||
|
||||
/**
|
||||
* Return the type of data stored in the column as indicated by wxVariant::GetType()
|
||||
|
@ -389,8 +395,13 @@ private:
|
|||
*/
|
||||
LIB_TREE_NODE* ShowSingleLibrary();
|
||||
|
||||
wxDataViewColumn* doAddColumn( const wxString& aHeader, bool aTranslate = true );
|
||||
|
||||
protected:
|
||||
LIB_TREE_NODE_ROOT m_tree;
|
||||
void addColumnIfNecessary( const wxString& aHeader );
|
||||
|
||||
LIB_TREE_NODE_ROOT m_tree;
|
||||
std::map<unsigned, wxString> m_colIdxMap;
|
||||
|
||||
private:
|
||||
[[maybe_unused]] EDA_BASE_FRAME* m_parent;
|
||||
|
@ -401,11 +412,11 @@ private:
|
|||
int m_preselect_unit;
|
||||
int m_freeze;
|
||||
|
||||
wxDataViewColumn* m_col_part;
|
||||
wxDataViewColumn* m_col_desc;
|
||||
wxDataViewCtrl* m_widget;
|
||||
|
||||
int m_colWidths[NUM_COLS];
|
||||
std::vector<wxDataViewColumn*> m_columns;
|
||||
std::map<wxString, wxDataViewColumn*> m_colNameMap;
|
||||
std::map<wxString, int> m_colWidths;
|
||||
};
|
||||
|
||||
#endif // LIB_TREE_MODEL_ADAPTER_H
|
||||
|
|
|
@ -127,7 +127,8 @@ public:
|
|||
|
||||
struct LIB_TREE
|
||||
{
|
||||
int column_width;
|
||||
std::vector<wxString> columns; ///< Ordered list of visible columns in the tree
|
||||
std::map<wxString, int> column_widths; ///< Column widths, keyed by header name
|
||||
};
|
||||
|
||||
struct PRINTING
|
||||
|
@ -211,6 +212,11 @@ protected:
|
|||
* @param aJsonPath is the path to read parameters from
|
||||
*/
|
||||
void addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath );
|
||||
|
||||
/**
|
||||
* Migrates the library tree width setting from a single column (Item) to multi-column
|
||||
*/
|
||||
bool migrateLibTreeWidth();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int fpEditSchemaVersion = 1;
|
||||
const int fpEditSchemaVersion = 2;
|
||||
|
||||
|
||||
FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
|
||||
|
@ -292,6 +292,13 @@ FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
|
|||
} ) );
|
||||
|
||||
registerMigration( 0, 1, std::bind( &FOOTPRINT_EDITOR_SETTINGS::migrateSchema0to1, this ) );
|
||||
|
||||
registerMigration( 1, 2,
|
||||
[&]() -> bool
|
||||
{
|
||||
// This is actually a migration for APP_SETTINGS_BASE::m_LibTree
|
||||
return migrateLibTreeWidth();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int pcbnewSchemaVersion = 3;
|
||||
const int pcbnewSchemaVersion = 4;
|
||||
|
||||
|
||||
PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
||||
|
@ -595,6 +595,13 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
|||
|
||||
return true;
|
||||
} );
|
||||
|
||||
registerMigration( 3, 4,
|
||||
[&]() -> bool
|
||||
{
|
||||
// This is actually a migration for APP_SETTINGS_BASE::m_LibTree
|
||||
return migrateLibTreeWidth();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue