BOM Generator: wire up to kicad-cli

This commit is contained in:
Mike Williams 2023-03-14 20:03:57 -04:00
parent 8433f94886
commit 753ae21fd4
19 changed files with 1053 additions and 424 deletions

View File

@ -0,0 +1,74 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Mike Williams <mike@mikebwilliams.com>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_SCH_BOM_H
#define JOB_EXPORT_SCH_BOM_H
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_SCH_BOM : public JOB
{
public:
JOB_EXPORT_SCH_BOM( bool aIsCli ) :
JOB( "bom", aIsCli ),
m_filename(),
m_outputFile(),
m_fieldDelimiter(),
m_stringDelimiter(),
m_refDelimiter(),
m_refRangeDelimiter(),
m_keepTabs( false ),
m_keepLineBreaks( false ),
m_fieldsOrdered(),
m_fieldsLabels(),
m_fieldsGroupBy(),
m_sortField(),
m_sortAsc( true ),
m_filterString(),
m_groupSymbols( true )
{
}
// Basic options
wxString m_filename;
wxString m_outputFile;
// Format options
wxString m_fieldDelimiter;
wxString m_stringDelimiter;
wxString m_refDelimiter;
wxString m_refRangeDelimiter;
bool m_keepTabs;
bool m_keepLineBreaks;
// Fields options
std::vector<wxString> m_fieldsOrdered;
std::vector<wxString> m_fieldsLabels;
std::vector<wxString> m_fieldsGroupBy;
wxString m_sortField;
bool m_sortAsc;
wxString m_filterString;
bool m_groupSymbols;
};
#endif

View File

@ -141,56 +141,6 @@ protected:
};
BOM_PRESET DIALOG_SYMBOL_FIELDS_TABLE::bomPresetGroupedByValue(
_HKI( "Grouped By Value" ),
std::map<std::string, bool>( {
std::pair<std::string, bool>( "Reference", true ),
std::pair<std::string, bool>( "Value", true ),
std::pair<std::string, bool>( "Datasheet", true ),
std::pair<std::string, bool>( "Footprint", true ),
std::pair<std::string, bool>( "Quantity", true ),
} ),
std::map<std::string, bool>( {
std::pair<std::string, bool>( "Reference", false ),
std::pair<std::string, bool>( "Value", true ),
std::pair<std::string, bool>( "Datasheet", false ),
std::pair<std::string, bool>( "Footprint", false ),
std::pair<std::string, bool>( "Quantity", false ),
} ),
std::map<std::string, int>(), std::vector<wxString>(), _( "Reference" ), true, _HKI( "" ),
true );
BOM_PRESET DIALOG_SYMBOL_FIELDS_TABLE::bomPresetGroupedByValueFootprint(
_HKI( "Grouped By Value and Footprint" ),
std::map<std::string, bool>( {
std::pair<std::string, bool>( "Reference", true ),
std::pair<std::string, bool>( "Value", true ),
std::pair<std::string, bool>( "Datasheet", true ),
std::pair<std::string, bool>( "Footprint", true ),
std::pair<std::string, bool>( "Quantity", true ),
} ),
std::map<std::string, bool>( {
std::pair<std::string, bool>( "Reference", false ),
std::pair<std::string, bool>( "Value", true ),
std::pair<std::string, bool>( "Datasheet", false ),
std::pair<std::string, bool>( "Footprint", true ),
std::pair<std::string, bool>( "Quantity", false ),
} ),
std::map<std::string, int>(), std::vector<wxString>(), _( "Reference" ), true, _HKI( "" ),
true );
BOM_FMT_PRESET DIALOG_SYMBOL_FIELDS_TABLE::bomFmtPresetCSV
( _HKI("CSV"), wxS( "," ), wxT( "\"" ), false, true, true);
BOM_FMT_PRESET DIALOG_SYMBOL_FIELDS_TABLE::bomFmtPresetTSV
( _HKI("TSV"), wxS( "\t" ), wxT(""), false, true, true);
BOM_FMT_PRESET DIALOG_SYMBOL_FIELDS_TABLE::bomFmtPresetSemicolons
( _HKI("Semicolons"), wxS( ";" ), wxT("'"), false, true, true);
DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent ) :
DIALOG_SYMBOL_FIELDS_TABLE_BASE( parent ), m_currentBomPreset( nullptr ),
m_lastSelectedBomPreset( nullptr ), m_parent( parent ),
@ -241,7 +191,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
m_fieldsCtrl->SetIndent( 0 );
m_filter->SetDescriptiveText( _( "Filter" ) );
m_dataModel = new FIELDS_EDITOR_GRID_DATA_MODEL( m_parent, m_symbolsList );
m_dataModel = new FIELDS_EDITOR_GRID_DATA_MODEL( m_symbolsList );
LoadFieldNames(); // loads rows into m_fieldsCtrl and columns into m_dataModel
@ -274,13 +224,6 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
m_splitterMainWindow->SetMinimumPaneSize( fieldsMinWidth );
m_splitterMainWindow->SetSashPosition( fieldsMinWidth + 40 );
m_cbBomPresets->SetToolTip( wxString::Format(
_( "Save and restore layer visibility combinations.\n"
"Use %s+Tab to activate selector.\n"
"Successive Tabs while holding %s down will "
"cycle through presets in the popup." ),
KeyNameFromKeyCode( PRESET_SWITCH_KEY ), KeyNameFromKeyCode( PRESET_SWITCH_KEY ) ) );
m_grid->UseNativeColHeader( true );
m_grid->SetTable( m_dataModel, true );
@ -295,12 +238,12 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
// Load our BOM view presets
SetUserBomPresets( m_schSettings.m_BomPresets );
ApplyBomPreset( bomPresetGroupedByValueFootprint );
ApplyBomPreset( SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint );
syncBomPresetSelection();
// Load BOM export format presets
SetUserBomFmtPresets( m_schSettings.m_BomFmtPresets );
ApplyBomFmtPreset( bomFmtPresetCSV );
ApplyBomFmtPreset( SCHEMATIC_SETTINGS::bomFmtPresetCSV );
syncBomFmtPresetSelection();
m_grid->SelectRow( 0 );
@ -377,11 +320,12 @@ void DIALOG_SYMBOL_FIELDS_TABLE::SetupColumnProperties()
// become unhidden.
if( m_grid->IsColShown( col ) )
{
EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
std::string key( m_dataModel->GetColFieldName( col ).ToUTF8() );
if( m_schSettings.m_BomSettings.column_widths.count( key ) )
if( cfg->m_FieldEditorPanel.field_widths.count( key ) )
{
int width = m_schSettings.m_BomSettings.column_widths.at( key );
int width = cfg->m_FieldEditorPanel.field_widths.at( key );
m_grid->SetColSize( col, width );
}
else
@ -396,10 +340,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::SetupColumnProperties()
}
}
if( m_schSettings.m_BomSettings.sort_field == m_dataModel->GetColFieldName( col ) )
if( m_schSettings.m_BomSettings.sortField == m_dataModel->GetColFieldName( col ) )
{
sortCol = col;
sortAscending = m_schSettings.m_BomSettings.sort_asc;
sortAscending = m_schSettings.m_BomSettings.sortAsc;
}
}
@ -500,7 +444,13 @@ bool DIALOG_SYMBOL_FIELDS_TABLE::TransferDataFromWindow()
SCH_SHEET_PATH currentSheet = m_parent->GetCurrentSheet();
m_dataModel->ApplyData();
std::function<void( SCH_SYMBOL&, SCH_SHEET_PATH & aPath )> changeHandler =
[this]( SCH_SYMBOL& aSymbol, SCH_SHEET_PATH& aPath ) -> void
{
m_parent->SaveCopyInUndoList( aPath.LastScreen(), &aSymbol, UNDO_REDO::CHANGED, true );
};
m_dataModel->ApplyData( changeHandler );
// Reset the view to where we left the user
m_parent->SetCurrentSheet( currentSheet );
@ -513,29 +463,20 @@ bool DIALOG_SYMBOL_FIELDS_TABLE::TransferDataFromWindow()
}
void DIALOG_SYMBOL_FIELDS_TABLE::AddField( const wxString& aFieldName,
const wxString& aLabelValue,
bool defaultShow, bool defaultSortBy, bool addedByUser )
void DIALOG_SYMBOL_FIELDS_TABLE::AddField( const wxString& aFieldName, const wxString& aLabelValue,
bool show, bool groupBy, bool addedByUser )
{
m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser );
wxVector<wxVariant> fieldsCtrlRow;
bool show = defaultShow;
bool sort_by = defaultSortBy;
std::string key( aFieldName.ToUTF8() );
if( m_schSettings.m_BomSettings.fields_show.count( key ) )
show = m_schSettings.m_BomSettings.fields_show.at( key );
if( m_schSettings.m_BomSettings.fields_group_by.count( key ) )
sort_by = m_schSettings.m_BomSettings.fields_group_by.at( key );
// Don't change these to emplace_back: some versions of wxWidgets don't support it
fieldsCtrlRow.push_back( wxVariant( aFieldName ) );
fieldsCtrlRow.push_back( wxVariant( aLabelValue ) );
fieldsCtrlRow.push_back( wxVariant( show ) );
fieldsCtrlRow.push_back( wxVariant( sort_by ) );
fieldsCtrlRow.push_back( wxVariant( groupBy ) );
fieldsCtrlRow.push_back( wxVariant( aFieldName ) );
m_fieldsCtrl->AppendItem( fieldsCtrlRow );
@ -622,7 +563,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnAddField( wxCommandEvent& event )
std::string key( fieldName.ToUTF8() );
m_parent->Schematic().Settings().m_BomSettings.fields_show[key] = true;
m_parent->Schematic().Settings().m_BomSettings.fieldsOrdered.emplace_back( key );
AddField( fieldName, fieldName, true, false, true );
wxGridTableMessage msg( m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
@ -740,21 +681,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnRenameField( wxCommandEvent& event )
m_dataModel->RenameColumn( col, newFieldName );
m_fieldsCtrl->SetTextValue( newFieldName, col, 0 );
std::string oldKey( fieldName.ToUTF8() );
std::string newKey( newFieldName.ToUTF8() );
//In-place rename map key
auto node = m_schSettings.m_BomSettings.fields_show.extract( oldKey );
node.key() = newKey;
m_schSettings.m_BomSettings.fields_show.insert( std::move( node ) );
syncBomPresetSelection();
}
void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterText( wxCommandEvent& aEvent )
{
m_schSettings.m_BomSettings.filter_string = m_filter->GetValue();
m_schSettings.m_BomSettings.filterString = m_filter->GetValue();
m_dataModel->SetFilter( m_filter->GetValue() );
m_dataModel->RebuildRows();
m_grid->ForceRefresh();
@ -804,11 +737,9 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
case SHOW_FIELD_COLUMN:
{
bool value = m_fieldsCtrl->GetToggleValue( row, col );
int dataCol = m_dataModel->GetFieldNameCol(
m_fieldsCtrl->GetTextValue( row, FIELD_NAME_COLUMN ) );
std::string fieldName( m_fieldsCtrl->GetTextValue( row, FIELD_NAME_COLUMN ).ToUTF8() );
m_schSettings.m_BomSettings.fields_show[fieldName] = value;
int dataCol = m_dataModel->GetFieldNameCol( fieldName );
m_dataModel->SetShowColumn( dataCol, value );
if( dataCol != -1 )
@ -835,8 +766,6 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
}
wxString fieldName = m_fieldsCtrl->GetTextValue( row, FIELD_NAME_COLUMN );
std::string fieldNameStr( fieldName.ToUTF8() );
m_schSettings.m_BomSettings.fields_group_by[fieldNameStr] = value;
m_dataModel->SetGroupColumn( m_dataModel->GetFieldNameCol( fieldName ), value );
m_dataModel->RebuildRows();
@ -854,7 +783,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
void DIALOG_SYMBOL_FIELDS_TABLE::OnGroupSymbolsToggled( wxCommandEvent& event )
{
m_schSettings.m_BomSettings.group_symbols = m_groupSymbolsBox->GetValue();
m_schSettings.m_BomSettings.groupSymbols = m_groupSymbolsBox->GetValue();
m_dataModel->SetGroupingEnabled( m_groupSymbolsBox->GetValue() );
m_dataModel->RebuildRows();
m_grid->ForceRefresh();
@ -883,8 +812,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColSort( wxGridEvent& aEvent )
}
// We only support sorting on one column at this time
m_schSettings.m_BomSettings.sort_field = m_dataModel->GetColFieldName( sortCol );
m_schSettings.m_BomSettings.sort_asc = ascending;
m_schSettings.m_BomSettings.sortField = m_dataModel->GetColFieldName( sortCol );
m_schSettings.m_BomSettings.sortAsc = ascending;
m_dataModel->SetSorting( sortCol, ascending );
m_dataModel->RebuildRows();
@ -905,7 +834,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColMove( wxGridEvent& aEvent )
m_dataModel->MoveColumn( origPos, newPos );
m_schSettings.m_BomSettings.column_order = m_dataModel->GetFieldsOrder();
m_schSettings.m_BomSettings.fieldsOrdered = m_dataModel->GetFieldsOrder();
// "Unmove" the column since we've moved the column internally
m_grid->ResetColPos();
@ -949,9 +878,6 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnTableColSize( wxGridSizeEvent& aEvent )
int col = aEvent.GetRowOrCol();
std::string key( m_dataModel->GetColFieldName( col ).ToUTF8() );
if( m_grid->GetColSize( col ) )
m_schSettings.m_BomSettings.column_widths[key] = m_grid->GetColSize( col );
aEvent.Skip();
m_grid->ForceRefresh();
@ -1074,9 +1000,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::PreviewRefresh()
current.fieldDelimiter = m_textFieldDelimiter->GetValue();
current.stringDelimiter = m_textStringDelimiter->GetValue();
current.spacedRefs = m_checkSpacedRefs->GetValue();
current.removeTabs = m_checkRemoveTabs->GetValue();
current.removeLineBreaks = m_checkRemoveLineBreaks->GetValue();
current.refDelimiter = m_textRefDelimiter->GetValue();
current.refRangeDelimiter = m_textRefRangeDelimiter->GetValue();
current.keepTabs = m_checkKeepTabs->GetValue();
current.keepLineBreaks = m_checkKeepLineBreaks->GetValue();
m_textOutput->SetValue( m_dataModel->Export( current ) );
}
@ -1274,7 +1201,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::loadDefaultBomPresets()
m_bomPresetMRU.clear();
// Load the read-only defaults
for( const BOM_PRESET& preset : { bomPresetGroupedByValue, bomPresetGroupedByValueFootprint } )
for( const BOM_PRESET& preset : { SCHEMATIC_SETTINGS::bomPresetGroupedByValue,
SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint } )
{
m_bomPresets[preset.name] = preset;
m_bomPresets[preset.name].readOnly = true;
@ -1298,7 +1226,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::rebuildBomPresetsWidget()
m_cbBomPresets->Append( wxGetTranslation( pair.first ),
static_cast<void*>( &pair.second ) );
if( pair.first == bomPresetGroupedByValueFootprint.name )
if( pair.first == SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint.name )
default_idx = idx;
idx++;
@ -1324,13 +1252,15 @@ void DIALOG_SYMBOL_FIELDS_TABLE::syncBomPresetSelection()
auto it = std::find_if( m_bomPresets.begin(), m_bomPresets.end(),
[&]( const std::pair<const wxString, BOM_PRESET>& aPair )
{
return ( aPair.second.fields_show == current.fields_show
&& aPair.second.fields_group_by == current.fields_group_by
&& aPair.second.sort_field == current.sort_field
&& aPair.second.sort_asc == current.sort_asc
&& aPair.second.column_order == current.column_order
&& aPair.second.filter_string == current.filter_string
&& aPair.second.group_symbols == current.group_symbols );
return ( aPair.second.fieldsOrdered == current.fieldsOrdered
&& aPair.second.fieldsLabels == current.fieldsLabels
&& aPair.second.fieldsShow == current.fieldsShow
&& aPair.second.fieldsGroupBy == current.fieldsGroupBy
&& aPair.second.sortField == current.sortField
&& aPair.second.sortAsc == current.sortAsc
&& aPair.second.fieldsOrdered == current.fieldsOrdered
&& aPair.second.filterString == current.filterString
&& aPair.second.groupSymbols == current.groupSymbols );
} );
if( it != m_bomPresets.end() )
@ -1426,14 +1356,14 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomPresetChanged( wxCommandEvent& aEvent )
if( !exists )
{
m_bomPresets[name] = BOM_PRESET( name, m_schSettings.m_BomSettings.fields_show,
m_schSettings.m_BomSettings.fields_group_by,
m_schSettings.m_BomSettings.column_widths,
m_schSettings.m_BomSettings.column_order,
m_schSettings.m_BomSettings.sort_field,
m_schSettings.m_BomSettings.sort_asc,
m_schSettings.m_BomSettings.filter_string,
m_schSettings.m_BomSettings.group_symbols );
m_bomPresets[name] = BOM_PRESET( name, m_schSettings.m_BomSettings.fieldsOrdered,
m_schSettings.m_BomSettings.fieldsLabels,
m_schSettings.m_BomSettings.fieldsShow,
m_schSettings.m_BomSettings.fieldsGroupBy,
m_schSettings.m_BomSettings.sortField,
m_schSettings.m_BomSettings.sortAsc,
m_schSettings.m_BomSettings.filterString,
m_schSettings.m_BomSettings.groupSymbols );
}
BOM_PRESET* preset = &m_bomPresets[name];
@ -1445,14 +1375,14 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomPresetChanged( wxCommandEvent& aEvent )
}
else
{
preset->fields_show = m_schSettings.m_BomSettings.fields_show;
preset->fields_group_by = m_schSettings.m_BomSettings.fields_group_by;
preset->column_widths = m_schSettings.m_BomSettings.column_widths;
preset->column_order = m_schSettings.m_BomSettings.column_order;
preset->sort_field = m_schSettings.m_BomSettings.sort_field;
preset->sort_asc = m_schSettings.m_BomSettings.sort_asc;
preset->filter_string = m_schSettings.m_BomSettings.filter_string;
preset->group_symbols = m_schSettings.m_BomSettings.group_symbols;
preset->fieldsOrdered = m_schSettings.m_BomSettings.fieldsOrdered;
preset->fieldsLabels = m_schSettings.m_BomSettings.fieldsLabels;
preset->fieldsShow = m_schSettings.m_BomSettings.fieldsShow;
preset->fieldsGroupBy = m_schSettings.m_BomSettings.fieldsGroupBy;
preset->sortField = m_schSettings.m_BomSettings.sortField;
preset->sortAsc = m_schSettings.m_BomSettings.sortAsc;
preset->filterString = m_schSettings.m_BomSettings.filterString;
preset->groupSymbols = m_schSettings.m_BomSettings.groupSymbols;
index = m_cbBomPresets->FindString( name );
m_bomPresetMRU.Remove( name );
@ -1526,71 +1456,79 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomPresetChanged( wxCommandEvent& aEvent )
void DIALOG_SYMBOL_FIELDS_TABLE::doApplyBomPreset( const BOM_PRESET& aPreset )
{
// Set a good default sort
int refCol = m_dataModel->GetFieldNameCol(
TEMPLATE_FIELDNAME::GetDefaultFieldName( REFERENCE_FIELD ) );
m_grid->SetSortingColumn( refCol, false );
// Basically, we apply the BOM preset to the data model and then
// update our UI to reflect resulting the data model state, not the preset.
m_dataModel->ApplyBomPreset( aPreset );
// BOM Presets can add, but not remove, columns, so make sure the field control
// grid has all of them before starting
for( int i = 0; i < m_dataModel->GetColsCount(); i++ )
{
const wxString& fieldName( m_dataModel->GetColFieldName( i ) );
bool found = false;
for( int j = 0; i < m_fieldsCtrl->GetItemCount(); j++ )
{
if( m_fieldsCtrl->GetTextValue( j, FIELD_NAME_COLUMN ) == fieldName )
{
found = true;
break;
}
}
// Properties like label, etc. will be added in the next loop
if( !found )
AddField( fieldName, fieldName, false, false );
}
// Sync all fields
for( int i = 0; i < m_fieldsCtrl->GetItemCount(); i++ )
{
const std::string fieldName( m_fieldsCtrl->GetTextValue( i, FIELD_NAME_COLUMN ).ToUTF8() );
const wxString& fieldName( m_fieldsCtrl->GetTextValue( i, FIELD_NAME_COLUMN ) );
int col = m_dataModel->GetFieldNameCol( fieldName );
if( col == -1 )
{
wxASSERT_MSG( true, "Fields control has a field not found in the data model." );
continue;
}
bool show = aPreset.fields_show.count( fieldName ) && aPreset.fields_show.at( fieldName );
bool groupBy = aPreset.fields_group_by.count( fieldName )
&& aPreset.fields_group_by.at( fieldName );
int width = aPreset.column_widths.count( fieldName ) ? aPreset.column_widths.at( fieldName )
: -1;
EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
std::string fieldNameStr( fieldName.ToUTF8() );
if( cfg->m_FieldEditorPanel.field_widths.count( fieldNameStr ) )
m_grid->SetColMinimalWidth( col,
cfg->m_FieldEditorPanel.field_widths.at( fieldNameStr ) );
// Set shown colums
bool show = m_dataModel->GetShowColumn( col );
m_fieldsCtrl->SetToggleValue( show, i, SHOW_FIELD_COLUMN );
m_dataModel->SetShowColumn( col, show );
if( show )
{
m_grid->ShowCol( col );
//m_grid->SetColSize( col, schSettings. );
}
else
m_grid->HideCol( col );
// Set grouped columns
bool groupBy = m_dataModel->GetGroupColumn( col );
m_fieldsCtrl->SetToggleValue( groupBy, i, GROUP_BY_COLUMN );
m_dataModel->SetGroupColumn( col, groupBy );
// Set sorting
if( aPreset.sort_field == fieldName )
{
m_dataModel->SetSorting( col, aPreset.sort_asc );
m_grid->SetSortingColumn( col, aPreset.sort_asc );
}
// Set grid column sizes
if( width != -1 )
m_grid->SetColSize( col, width );
}
m_dataModel->SetGroupingEnabled( aPreset.group_symbols );
m_groupSymbolsBox->SetValue( aPreset.group_symbols );
m_dataModel->SetFieldsOrder( aPreset.column_order );
m_dataModel->SetFilter( aPreset.filter_string );
m_filter->ChangeValue( aPreset.filter_string );
m_grid->SetSortingColumn( m_dataModel->GetSortCol(), m_dataModel->GetSortAsc() );
m_groupSymbolsBox->SetValue( m_dataModel->GetGroupingEnabled() );
m_filter->ChangeValue( m_dataModel->GetFilter() );
SetupColumnProperties();
// This will rebuild all rows and columns in the model such that the order
// and labels are right, then we refresh the shown grid data to match
m_dataModel->RebuildRows();
m_grid->ForceRefresh();
m_schSettings.m_BomSettings.fields_show = aPreset.fields_show;
m_schSettings.m_BomSettings.fields_group_by = aPreset.fields_group_by;
m_schSettings.m_BomSettings.column_widths = aPreset.column_widths;
m_schSettings.m_BomSettings.sort_field = aPreset.sort_field;
m_schSettings.m_BomSettings.sort_asc = aPreset.sort_asc;
m_schSettings.m_BomSettings.column_order = aPreset.column_order;
m_schSettings.m_BomSettings.filter_string = aPreset.filter_string;
m_schSettings.m_BomSettings.group_symbols = aPreset.group_symbols;
m_schSettings.m_BomSettings = aPreset;
}
@ -1659,7 +1597,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::loadDefaultBomFmtPresets()
// Load the read-only defaults
for( const BOM_FMT_PRESET& preset :
{ bomFmtPresetCSV, bomFmtPresetSemicolons, bomFmtPresetTSV } )
{ SCHEMATIC_SETTINGS::bomFmtPresetCSV, SCHEMATIC_SETTINGS::bomFmtPresetSemicolons,
SCHEMATIC_SETTINGS::bomFmtPresetTSV } )
{
m_bomFmtPresets[preset.name] = preset;
m_bomFmtPresets[preset.name].readOnly = true;
@ -1683,7 +1622,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::rebuildBomFmtPresetsWidget()
m_cbBomFmtPresets->Append( wxGetTranslation( pair.first ),
static_cast<void*>( &pair.second ) );
if( pair.first == bomFmtPresetCSV.name )
if( pair.first == SCHEMATIC_SETTINGS::bomFmtPresetCSV.name )
default_idx = idx;
idx++;
@ -1712,9 +1651,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::syncBomFmtPresetSelection()
{
return ( aPair.second.fieldDelimiter == current.fieldDelimiter
&& aPair.second.stringDelimiter == current.stringDelimiter
&& aPair.second.spacedRefs == current.spacedRefs
&& aPair.second.removeTabs == current.removeTabs
&& aPair.second.removeLineBreaks == current.removeLineBreaks );
&& aPair.second.refDelimiter == current.refDelimiter
&& aPair.second.refRangeDelimiter == current.refRangeDelimiter
&& aPair.second.keepTabs == current.keepTabs
&& aPair.second.keepLineBreaks == current.keepLineBreaks );
} );
if( it != m_bomFmtPresets.end() )
@ -1811,12 +1751,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomFmtPresetChanged( wxCommandEvent& aEvent )
if( !exists )
{
m_bomFmtPresets[name] = BOM_FMT_PRESET( name,
m_schSettings.m_BomFmtSettings.fieldDelimiter,
m_bomFmtPresets[name] =
BOM_FMT_PRESET( name, m_schSettings.m_BomFmtSettings.fieldDelimiter,
m_schSettings.m_BomFmtSettings.stringDelimiter,
m_schSettings.m_BomFmtSettings.spacedRefs,
m_schSettings.m_BomFmtSettings.removeTabs,
m_schSettings.m_BomFmtSettings.removeLineBreaks );
m_schSettings.m_BomFmtSettings.refDelimiter,
m_schSettings.m_BomFmtSettings.refRangeDelimiter,
m_schSettings.m_BomFmtSettings.keepTabs,
m_schSettings.m_BomFmtSettings.keepLineBreaks );
}
BOM_FMT_PRESET* preset = &m_bomFmtPresets[name];
@ -1830,9 +1771,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomFmtPresetChanged( wxCommandEvent& aEvent )
{
preset->fieldDelimiter = m_schSettings.m_BomFmtSettings.fieldDelimiter;
preset->stringDelimiter = m_schSettings.m_BomFmtSettings.stringDelimiter;
preset->spacedRefs = m_schSettings.m_BomFmtSettings.spacedRefs;
preset->removeTabs = m_schSettings.m_BomFmtSettings.removeTabs;
preset->removeLineBreaks = m_schSettings.m_BomFmtSettings.removeLineBreaks;
preset->refDelimiter = m_schSettings.m_BomFmtSettings.refDelimiter;
preset->refRangeDelimiter = m_schSettings.m_BomFmtSettings.refRangeDelimiter;
preset->keepTabs = m_schSettings.m_BomFmtSettings.keepTabs;
preset->keepLineBreaks = m_schSettings.m_BomFmtSettings.keepLineBreaks;
index = m_cbBomFmtPresets->FindString( name );
m_bomFmtPresetMRU.Remove( name );
@ -1909,15 +1851,17 @@ void DIALOG_SYMBOL_FIELDS_TABLE::doApplyBomFmtPreset( const BOM_FMT_PRESET& aPre
{
m_textFieldDelimiter->ChangeValue( aPreset.fieldDelimiter );
m_textStringDelimiter->ChangeValue( aPreset.stringDelimiter );
m_checkSpacedRefs->SetValue( aPreset.spacedRefs );
m_checkRemoveTabs->SetValue( aPreset.removeTabs );
m_checkRemoveLineBreaks->SetValue( aPreset.removeLineBreaks );
m_textRefDelimiter->SetValue( aPreset.refDelimiter );
m_textRefRangeDelimiter->SetValue( aPreset.refRangeDelimiter );
m_checkKeepTabs->SetValue( aPreset.keepTabs );
m_checkKeepLineBreaks->SetValue( aPreset.keepLineBreaks );
PreviewRefresh();
m_schSettings.m_BomFmtSettings.fieldDelimiter = aPreset.fieldDelimiter;
m_schSettings.m_BomFmtSettings.stringDelimiter = aPreset.stringDelimiter;
m_schSettings.m_BomFmtSettings.spacedRefs = aPreset.spacedRefs;
m_schSettings.m_BomFmtSettings.removeTabs = aPreset.removeTabs;
m_schSettings.m_BomFmtSettings.removeLineBreaks = aPreset.removeLineBreaks;
m_schSettings.m_BomFmtSettings.refDelimiter = aPreset.refDelimiter;
m_schSettings.m_BomFmtSettings.refRangeDelimiter = aPreset.refRangeDelimiter;
m_schSettings.m_BomFmtSettings.keepTabs = aPreset.keepTabs;
m_schSettings.m_BomFmtSettings.keepLineBreaks = aPreset.keepLineBreaks;
}

View File

@ -48,8 +48,8 @@ public:
private:
void SetupColumnProperties();
void AddField( const wxString& displayName, const wxString& aCanonicalName, bool defaultShow,
bool defaultSortBy, bool addedByUser = false );
void AddField( const wxString& displayName, const wxString& aCanonicalName, bool show,
bool groupBy, bool addedByUser = false );
/**
* Construct the rows of m_fieldsCtrl and the columns of m_dataModel from a union of all
@ -109,9 +109,6 @@ private:
BOM_PRESET* m_lastSelectedBomPreset;
wxArrayString m_bomPresetMRU;
static BOM_PRESET bomPresetGroupedByValue;
static BOM_PRESET bomPresetGroupedByValueFootprint;
void syncBomFmtPresetSelection();
void rebuildBomFmtPresetsWidget();
void updateBomFmtPresetSelection( const wxString& aName );
@ -124,10 +121,6 @@ private:
BOM_FMT_PRESET* m_lastSelectedBomFmtPreset;
wxArrayString m_bomFmtPresetMRU;
static BOM_FMT_PRESET bomFmtPresetCSV;
static BOM_FMT_PRESET bomFmtPresetSemicolons;
static BOM_FMT_PRESET bomFmtPresetTSV;
SCH_EDIT_FRAME* m_parent;
int m_fieldNameColWidth;
int m_labelColWidth;

View File

@ -167,8 +167,7 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
gbExport->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxFlexGridSizer* fgExportOptions;
fgExportOptions = new wxFlexGridSizer( 6, 2, 0, 0 );
fgExportOptions->AddGrowableRow( 5 );
fgExportOptions = new wxFlexGridSizer( 7, 2, 0, 0 );
fgExportOptions->SetFlexibleDirection( wxBOTH );
fgExportOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
@ -196,28 +195,35 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_textStringDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _("\""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
fgExportOptions->Add( m_textStringDelimiter, 0, wxALL|wxEXPAND, 5 );
m_labelSpacedRefs = new wxStaticText( m_panelExport, wxID_ANY, _("Spaced References:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSpacedRefs->Wrap( -1 );
fgExportOptions->Add( m_labelSpacedRefs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_labelRefDelimiter = new wxStaticText( m_panelExport, wxID_ANY, _("Reference Delimiter:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelRefDelimiter->Wrap( -1 );
fgExportOptions->Add( m_labelRefDelimiter, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkSpacedRefs = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgExportOptions->Add( m_checkSpacedRefs, 0, wxALL, 5 );
m_textRefDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _(","), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
fgExportOptions->Add( m_textRefDelimiter, 0, wxALL, 5 );
m_labelRemoveTabs = new wxStaticText( m_panelExport, wxID_ANY, _("Remove Tabs:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelRemoveTabs->Wrap( -1 );
fgExportOptions->Add( m_labelRemoveTabs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_labelRefRangeDelimiter = new wxStaticText( m_panelExport, wxID_ANY, _("Range Delimiter:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelRefRangeDelimiter->Wrap( -1 );
fgExportOptions->Add( m_labelRefRangeDelimiter, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkRemoveTabs = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_checkRemoveTabs->SetValue(true);
fgExportOptions->Add( m_checkRemoveTabs, 0, wxALL, 5 );
m_textRefRangeDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _("-"), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
m_textRefRangeDelimiter->SetToolTip( _("Leave blank to disable ranges.") );
m_labelRemoveLineBreaks = new wxStaticText( m_panelExport, wxID_ANY, _("Remove Line Breaks:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelRemoveLineBreaks->Wrap( -1 );
fgExportOptions->Add( m_labelRemoveLineBreaks, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
fgExportOptions->Add( m_textRefRangeDelimiter, 0, wxALL, 5 );
m_checkRemoveLineBreaks = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_checkRemoveLineBreaks->SetValue(true);
fgExportOptions->Add( m_checkRemoveLineBreaks, 0, wxALL, 5 );
m_labelKeepTabs = new wxStaticText( m_panelExport, wxID_ANY, _("Keep Tabs:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelKeepTabs->Wrap( -1 );
fgExportOptions->Add( m_labelKeepTabs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkKeepTabs = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgExportOptions->Add( m_checkKeepTabs, 0, wxALL, 5 );
m_labelKeepLineBreaks = new wxStaticText( m_panelExport, wxID_ANY, _("Keep Line Breaks:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelKeepLineBreaks->Wrap( -1 );
fgExportOptions->Add( m_labelKeepLineBreaks, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkKeepLineBreaks = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgExportOptions->Add( m_checkKeepLineBreaks, 0, wxALL, 5 );
gbExport->Add( fgExportOptions, wxGBPosition( 0, 0 ), wxGBSpan( 3, 1 ), wxEXPAND, 5 );
@ -326,9 +332,10 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_grid->Connect( wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableRangeSelected ), NULL, this );
m_textFieldDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textStringDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkSpacedRefs->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkRemoveTabs->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkRemoveLineBreaks->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefRangeDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkKeepTabs->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkKeepLineBreaks->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnOutputFileBrowseClicked ), NULL, this );
m_bRefreshPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_buttonExport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExport ), NULL, this );
@ -359,9 +366,10 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::~DIALOG_SYMBOL_FIELDS_TABLE_BASE()
m_grid->Disconnect( wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableRangeSelected ), NULL, this );
m_textFieldDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textStringDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkSpacedRefs->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkRemoveTabs->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkRemoveLineBreaks->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefRangeDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkKeepTabs->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_checkKeepLineBreaks->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnOutputFileBrowseClicked ), NULL, this );
m_bRefreshPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_buttonExport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExport ), NULL, this );

View File

@ -1436,13 +1436,13 @@
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows">5</property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">fgExportOptions</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">6</property>
<property name="rows">7</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
@ -1853,7 +1853,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Spaced References:</property>
<property name="label">Reference Delimiter:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -1862,7 +1862,259 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_labelSpacedRefs</property>
<property name="name">m_labelRefDelimiter</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_textRefDelimiter</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxTE_PROCESS_TAB</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">,</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnText">OnPreviewRefresh</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Range Delimiter:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_labelRefRangeDelimiter</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_textRefRangeDelimiter</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxTE_PROCESS_TAB</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Leave blank to disable ranges.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">-</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnText">OnPreviewRefresh</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Keep Tabs:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_labelKeepTabs</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -1923,7 +2175,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkSpacedRefs</property>
<property name="name">m_checkKeepTabs</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -1979,7 +2231,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Remove Tabs:</property>
<property name="label">Keep Line Breaks:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -1988,7 +2240,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_labelRemoveTabs</property>
<property name="name">m_labelKeepLineBreaks</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -2026,7 +2278,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -2049,133 +2301,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkRemoveTabs</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">OnPreviewRefresh</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Remove Line Breaks:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_labelRemoveLineBreaks</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label"></property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkRemoveLineBreaks</property>
<property name="name">m_checkKeepLineBreaks</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>

View File

@ -76,12 +76,14 @@ class DIALOG_SYMBOL_FIELDS_TABLE_BASE : public DIALOG_SHIM
wxTextCtrl* m_textFieldDelimiter;
wxStaticText* m_labelStringDelimiter;
wxTextCtrl* m_textStringDelimiter;
wxStaticText* m_labelSpacedRefs;
wxCheckBox* m_checkSpacedRefs;
wxStaticText* m_labelRemoveTabs;
wxCheckBox* m_checkRemoveTabs;
wxStaticText* m_labelRemoveLineBreaks;
wxCheckBox* m_checkRemoveLineBreaks;
wxStaticText* m_labelRefDelimiter;
wxTextCtrl* m_textRefDelimiter;
wxStaticText* m_labelRefRangeDelimiter;
wxTextCtrl* m_textRefRangeDelimiter;
wxStaticText* m_labelKeepTabs;
wxCheckBox* m_checkKeepTabs;
wxStaticText* m_labelKeepLineBreaks;
wxCheckBox* m_checkKeepLineBreaks;
wxStaticText* m_labelOutputDirectory;
wxTextCtrl* m_outputFileName;
wxBitmapButton* m_browseButton;

View File

@ -22,6 +22,7 @@
#include <pgm_base.h>
#include <cli/exit_codes.h>
#include <sch_plotter.h>
#include <jobs/job_export_sch_bom.h>
#include <jobs/job_export_sch_pythonbom.h>
#include <jobs/job_export_sch_netlist.h>
#include <jobs/job_export_sch_plot.h>
@ -55,9 +56,13 @@
#include <netlist_exporter_kicad.h>
#include <netlist_exporter_xml.h>
#include <fields_data_model.h>
EESCHEMA_JOBS_HANDLER::EESCHEMA_JOBS_HANDLER()
{
Register( "bom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ) );
Register( "pythonbom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ) );
Register( "netlist",
@ -230,6 +235,125 @@ int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob )
}
int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob )
{
JOB_EXPORT_SCH_BOM* aBomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( aJob );
if( !aBomJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aBomJob->m_filename, SCH_IO_MGR::SCH_KICAD );
if( sch == nullptr )
{
wxFprintf( stderr, _( "Failed to load schematic file\n" ) );
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
// Annotation warning check
SCH_REFERENCE_LIST referenceList;
sch->GetSheets().GetSymbols( referenceList, false, false );
if( referenceList.GetCount() > 0 )
{
SCH_REFERENCE_LIST copy = referenceList;
// Check annotation splits references...
if( copy.CheckAnnotation( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* ) {} ) > 0 )
{
wxPrintf( _( "Warning: schematic has annotation errors, please use the schematic "
"editor to fix them\n" ) );
}
}
// Test duplicate sheet names:
ERC_TESTER erc( sch );
if( erc.TestDuplicateSheetNames( false ) > 0 )
{
wxPrintf( _( "Warning: duplicate sheet names.\n" ) );
}
// Build our data model
FIELDS_EDITOR_GRID_DATA_MODEL dataModel( referenceList );
// Mandatory fields + quantity virtual field first
for( int i = 0; i < MANDATORY_FIELDS; ++i )
dataModel.AddColumn( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ),
TEMPLATE_FIELDNAME::GetDefaultFieldName( i, true ), false );
dataModel.AddColumn( wxS( "Quantity" ), _( "Qty" ), false );
// User field names in symbols second
std::set<wxString> userFieldNames;
for( size_t i = 0; i < referenceList.GetCount(); ++i )
{
SCH_SYMBOL* symbol = referenceList[i].GetSymbol();
for( int j = MANDATORY_FIELDS; j < symbol->GetFieldCount(); ++j )
userFieldNames.insert( symbol->GetFields()[j].GetName() );
}
for( const wxString& fieldName : userFieldNames )
dataModel.AddColumn( fieldName, fieldName, true );
// Add any templateFieldNames which aren't already present in the userFieldNames
for( const TEMPLATE_FIELDNAME& templateFieldname :
sch->Settings().m_TemplateFieldNames.GetTemplateFieldNames() )
{
if( userFieldNames.count( templateFieldname.m_Name ) == 0 )
dataModel.AddColumn( templateFieldname.m_Name, templateFieldname.m_Name, false );
}
BOM_PRESET preset;
preset.fieldsOrdered = aBomJob->m_fieldsOrdered;
preset.fieldsLabels = aBomJob->m_fieldsLabels;
preset.fieldsShow = aBomJob->m_fieldsOrdered;
preset.fieldsGroupBy = aBomJob->m_fieldsGroupBy;
preset.sortAsc = aBomJob->m_sortAsc;
preset.sortField = aBomJob->m_sortField;
preset.groupSymbols = aBomJob->m_groupSymbols;
preset.filterString = aBomJob->m_filterString;
dataModel.ApplyBomPreset( preset );
if( aBomJob->m_outputFile.IsEmpty() )
{
wxFileName fn = sch->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( CsvFileExtension );
aBomJob->m_outputFile = fn.GetFullName();
}
wxFile f;
if( !f.Open( aBomJob->m_outputFile, wxFile::write ) )
{
wxFprintf( stderr, _( "Unable to open destination '%s'" ), aBomJob->m_outputFile );
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
BOM_FMT_PRESET fmt;
fmt.fieldDelimiter = aBomJob->m_fieldDelimiter;
fmt.stringDelimiter = aBomJob->m_stringDelimiter;
fmt.refDelimiter = aBomJob->m_refDelimiter;
fmt.refRangeDelimiter = aBomJob->m_refRangeDelimiter;
fmt.keepTabs = aBomJob->m_keepTabs;
fmt.keepLineBreaks = aBomJob->m_keepLineBreaks;
bool res = f.Write( dataModel.Export( fmt ) );
if( !res )
{
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
return CLI::EXIT_CODES::OK;
}
int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
{
JOB_EXPORT_SCH_PYTHONBOM* aNetJob = dynamic_cast<JOB_EXPORT_SCH_PYTHONBOM*>( aJob );

View File

@ -41,6 +41,7 @@ class EESCHEMA_JOBS_HANDLER : public JOB_DISPATCHER, REPORTER
{
public:
EESCHEMA_JOBS_HANDLER();
int JobExportBom( JOB* aJob );
int JobExportPythonBom( JOB* aJob );
int JobExportNetlist( JOB* aJob );
int JobExportPlot( JOB* aJob );

View File

@ -194,6 +194,7 @@ public:
struct PANEL_FIELD_EDITOR
{
std::map<std::string, int> field_widths;
};
struct PANEL_LIB_VIEW

View File

@ -3,7 +3,7 @@
#include <wx/grid.h>
#include <widgets/wx_grid.h>
#include <sch_reference_list.h>
#include <sch_edit_frame.h>
#include <schematic_settings.h>
#include "string_utils.h"
#include "fields_data_model.h"
@ -12,6 +12,10 @@
void FIELDS_EDITOR_GRID_DATA_MODEL::AddColumn( const wxString& aFieldName, const wxString& aLabel,
bool aAddedByUser )
{
// Don't add a field twice
if( GetFieldNameCol( aFieldName ) != -1 )
return;
m_cols.push_back((struct DATA_MODEL_COL) {
.m_fieldName = aFieldName,
.m_label = aLabel,
@ -127,7 +131,8 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::GetValue( int aRow, int aCol )
wxString FIELDS_EDITOR_GRID_DATA_MODEL::GetValue( const DATA_MODEL_ROW& group, int aCol,
bool spacedRefs )
const wxString& refDelimiter,
const wxString& refRangeDelimiter )
{
std::vector<SCH_REFERENCE> references;
wxString fieldValue;
@ -183,7 +188,7 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::GetValue( const DATA_MODEL_ROW& group, i
}
if( ColIsReference( aCol ) )
fieldValue = SCH_REFERENCE_LIST::Shorthand( references, spacedRefs );
fieldValue = SCH_REFERENCE_LIST::Shorthand( references, refDelimiter, refRangeDelimiter );
else if( ColIsQuantity( aCol ) )
fieldValue = wxString::Format( wxT( "%d" ), (int) references.size() );
@ -493,14 +498,14 @@ void FIELDS_EDITOR_GRID_DATA_MODEL::ExpandAfterSort()
}
void FIELDS_EDITOR_GRID_DATA_MODEL::ApplyData()
void FIELDS_EDITOR_GRID_DATA_MODEL::ApplyData(
std::function<void( SCH_SYMBOL&, SCH_SHEET_PATH& )> symbolChangeHandler )
{
for( unsigned i = 0; i < m_symbolsList.GetCount(); ++i )
{
SCH_SYMBOL& symbol = *m_symbolsList[i].GetSymbol();
SCH_SCREEN* screen = m_symbolsList[i].GetSheetPath().LastScreen();
m_frame->SaveCopyInUndoList( screen, &symbol, UNDO_REDO::CHANGED, true );
symbolChangeHandler( symbol, m_symbolsList[i].GetSheetPath() );
const std::map<wxString, wxString>& fieldStore = m_dataStore[symbol.m_Uuid];
@ -583,10 +588,67 @@ int FIELDS_EDITOR_GRID_DATA_MODEL::GetDataWidth( int aCol )
}
void FIELDS_EDITOR_GRID_DATA_MODEL::ApplyBomPreset( const BOM_PRESET& aPreset )
{
// Hide and un-group everything by default
for( size_t i = 0; i < m_cols.size(); i++ )
{
SetShowColumn( i, false );
SetGroupColumn( i, false );
}
// Set columns that are present and shown
for( size_t i = 0; i < aPreset.fieldsOrdered.size(); i++ )
{
const wxString& fieldName = aPreset.fieldsOrdered[i];
const wxString& label =
i < aPreset.fieldsLabels.size() ? aPreset.fieldsLabels[i] : fieldName;
int col = GetFieldNameCol( fieldName );
// Add any missing fields, if the user doesn't add any data
// they won't be saved to the symbols anywa
if( col == -1 )
AddColumn( fieldName, label, true );
else
SetColLabelValue( col, label );
SetShowColumn( col, true );
}
// Set grouping columns
SetGroupingEnabled( aPreset.groupSymbols );
for( auto fieldName : aPreset.fieldsGroupBy )
{
int col = GetFieldNameCol( fieldName );
if( col != -1 )
SetGroupColumn( col, true );
}
SetFieldsOrder( aPreset.fieldsOrdered );
// Set our sorting
int sortCol = GetFieldNameCol( aPreset.sortField );
if( sortCol != -1 )
SetSorting( sortCol, aPreset.sortAsc );
else
SetSorting( GetFieldNameCol( TEMPLATE_FIELDNAME::GetDefaultFieldName( REFERENCE_FIELD ) ),
aPreset.sortAsc );
SetFilter( aPreset.filterString );
RebuildRows();
}
wxString FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings )
{
wxString out;
if( m_cols.empty() )
return out;
size_t last_col = m_cols.size() - 1;
// Find the location for the line terminator
@ -601,13 +663,13 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings )
auto formatField = [&]( wxString field, bool last ) -> wxString
{
if( settings.removeLineBreaks )
if( !settings.keepLineBreaks )
{
field.Replace( wxS( "\r" ), wxS( "" ) );
field.Replace( wxS( "\n" ), wxS( "" ) );
}
if( settings.removeTabs )
if( !settings.keepTabs )
{
field.Replace( wxS( "\t" ), wxS( "" ) );
}
@ -642,7 +704,8 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings )
continue;
// Get the unanottated version of the field, e.g. no "> " or "v " by
out.Append( formatField( GetRawValue( (int) row, (int) col, settings.spacedRefs ),
out.Append( formatField( GetRawValue( (int) row, (int) col, settings.refDelimiter,
settings.refRangeDelimiter ),
col == last_col ) );
}
}

View File

@ -10,6 +10,8 @@
// The internal field name (untranslated)
#define FIELD_NAME_COLUMN 4
struct BOM_PRESET;
struct BOM_FMT_PRESET;
enum GROUP_TYPE
{
@ -47,8 +49,8 @@ struct DATA_MODEL_COL
class FIELDS_EDITOR_GRID_DATA_MODEL : public wxGridTableBase
{
public:
FIELDS_EDITOR_GRID_DATA_MODEL( SCH_EDIT_FRAME* aFrame, SCH_REFERENCE_LIST& aSymbolsList ) :
m_frame( aFrame ), m_symbolsList( aSymbolsList ), m_edited( false ), m_sortColumn( 0 ),
FIELDS_EDITOR_GRID_DATA_MODEL( SCH_REFERENCE_LIST& aSymbolsList ) :
m_symbolsList( aSymbolsList ), m_edited( false ), m_sortColumn( 0 ),
m_sortAscending( false ), m_groupingEnabled( false )
{
m_symbolsList.SplitReferences();
@ -96,10 +98,13 @@ public:
}
wxString GetValue( int aRow, int aCol ) override;
wxString GetValue( const DATA_MODEL_ROW& group, int aCol, bool spacedRefs = true );
wxString GetRawValue( int aRow, int aCol, bool spacedRefs )
wxString GetValue( const DATA_MODEL_ROW& group, int aCol,
const wxString& refDelimiter = wxT( ", " ),
const wxString& refRangeDelimiter = wxT( "-" ) );
wxString GetRawValue( int aRow, int aCol, const wxString& refDelimiter,
const wxString& refRangeDelimiter )
{
return GetValue( m_rows[aRow], aCol, spacedRefs );
return GetValue( m_rows[aRow], aCol, refDelimiter, refRangeDelimiter );
}
void SetValue( int aRow, int aCol, const wxString& aValue ) override;
@ -120,6 +125,8 @@ public:
m_sortColumn = aCol;
m_sortAscending = ascending;
}
int GetSortCol() { return m_sortColumn; }
bool GetSortAsc() { return m_sortAscending; }
void RebuildRows();
void ExpandRow( int aRow );
@ -128,26 +135,41 @@ public:
void CollapseForSort();
void ExpandAfterSort();
void ApplyData();
void ApplyData( std::function<void( SCH_SYMBOL&, SCH_SHEET_PATH& )> symbolChangeHandler );
bool IsEdited() { return m_edited; }
int GetDataWidth( int aCol );
void SetFilter( const wxString& aFilter ) { m_filter = aFilter; }
const wxString& GetFilter() { return m_filter; }
void SetGroupingEnabled( bool group ) { m_groupingEnabled = group; }
bool GetGroupingEnabled() { return m_groupingEnabled; }
void SetGroupColumn( int aCol, bool group )
{
wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
m_cols[aCol].m_group = group;
}
bool GetGroupColumn( int aCol )
{
wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
return m_cols[aCol].m_group;
}
void SetShowColumn( int aCol, bool show )
{
wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
m_cols[aCol].m_show = show;
}
bool GetShowColumn( int aCol )
{
wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
return m_cols[aCol].m_show;
}
void ApplyBomPreset( const BOM_PRESET& preset );
wxString Export( const BOM_FMT_PRESET& settings );
private:
@ -160,7 +182,6 @@ private:
protected:
SCH_EDIT_FRAME* m_frame;
SCH_REFERENCE_LIST m_symbolsList;
bool m_edited;
int m_sortColumn;

View File

@ -922,7 +922,9 @@ bool SCH_REFERENCE::IsSplitNeeded()
}
wxString SCH_REFERENCE_LIST::Shorthand( std::vector<SCH_REFERENCE> aList, bool spaced )
wxString SCH_REFERENCE_LIST::Shorthand( std::vector<SCH_REFERENCE> aList,
const wxString& refDelimiter,
const wxString& refRangeDelimiter )
{
wxString retVal;
size_t i = 0;
@ -939,25 +941,28 @@ wxString SCH_REFERENCE_LIST::Shorthand( std::vector<SCH_REFERENCE> aList, bool s
&& aList[ i + range ].m_numRef == int( numRef + range ) )
{
range++;
if( range == 2 && refRangeDelimiter.IsEmpty() )
break;
}
if( !retVal.IsEmpty() )
retVal << ( spaced ? wxT( ", " ) : wxT( "," ) );
retVal << refDelimiter;
if( range == 1 )
{
retVal << ref << aList[ i ].GetRefNumber();
}
else if( range == 2 )
else if( range == 2 || refRangeDelimiter.IsEmpty() )
{
retVal << ref << aList[ i ].GetRefNumber();
retVal << ( spaced ? wxT( ", " ) : wxT( "," ) );
retVal << refDelimiter;
retVal << ref << aList[ i + 1 ].GetRefNumber();
}
else
{
retVal << ref << aList[ i ].GetRefNumber();
retVal << wxT( "-" );
retVal << refRangeDelimiter;
retVal << ref << aList[ i + ( range - 1 ) ].GetRefNumber();
}

View File

@ -587,7 +587,8 @@ public:
* "R1, R2, R4 - R7, U1"
* @param spaced Add spaces between references
*/
static wxString Shorthand( std::vector<SCH_REFERENCE> aList, bool spaced = true );
static wxString Shorthand( std::vector<SCH_REFERENCE> aList, const wxString& refDelimiter,
const wxString& refRangeDelimiter );
friend class BACK_ANNOTATION;

View File

@ -30,11 +30,42 @@
#include <settings/parameters.h>
#include <settings/settings_manager.h>
#include <sim/spice_settings.h>
#include <i18n_utility.h>
const int schSettingsSchemaVersion = 1;
BOM_PRESET SCHEMATIC_SETTINGS::bomPresetGroupedByValue(
_HKI( "Grouped By Value and Footprint" ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Quantity" } ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Qty" } ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Quantity" } ),
std::vector<wxString>( { "Value" } ), _( "Reference" ), true, _HKI( "" ), true );
BOM_PRESET SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint(
_HKI( "Grouped By Value and Footprint" ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Quantity" } ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Qty" } ),
std::vector<wxString>( { "Reference", "Value", "Datasheet", "Footprint", "Quantity" } ),
std::vector<wxString>( { "Value", "Footprint" } ), _( "Reference" ), true, _HKI( "" ),
true );
BOM_FMT_PRESET SCHEMATIC_SETTINGS::bomFmtPresetCSV( _HKI( "CSV" ), wxS( "," ), wxT( "\"" ),
wxT( "," ), wxT( "" ), false, false );
BOM_FMT_PRESET SCHEMATIC_SETTINGS::bomFmtPresetTSV( _HKI( "TSV" ), wxS( "\t" ), wxT( "" ),
wxT( "," ), wxT( "" ), false, false );
BOM_FMT_PRESET SCHEMATIC_SETTINGS::bomFmtPresetSemicolons( _HKI( "Semicolons" ), wxS( ";" ),
wxT( "'" ), wxT( "," ), wxT( "" ), false,
false );
SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "schematic", schSettingsSchemaVersion, aParent, aPath ),
m_DefaultLineWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS ),

View File

@ -20,6 +20,8 @@
#ifndef KICAD_SCHEMATIC_SETTINGS_H
#define KICAD_SCHEMATIC_SETTINGS_H
#include <set>
#include <default_values.h>
#include <settings/nested_settings.h>
#include <template_fieldnames.h>
@ -30,40 +32,30 @@ class NGSPICE_SIMULATOR_SETTINGS;
struct BOM_PRESET
{
BOM_PRESET( const wxString& aName = wxEmptyString ) :
name( aName ), readOnly(false), sort_asc( true ), group_symbols( false) { }
BOM_PRESET( const wxString& aName = wxEmptyString ) : name( aName ) {}
BOM_PRESET( const wxString& aName,
const std::map<std::string, bool>& aFieldsShow,
const std::map<std::string, bool>& aFieldsGroupBy,
const std::map<std::string, int>& aColumnWidths,
const std::vector<wxString>& aColumnOrder,
const wxString& aSortField,
bool aSortAscending,
const wxString& aFilterString,
bool aGroupSymbols
) :
BOM_PRESET( const wxString& aName, const std::vector<wxString>& aFieldsOrdered,
const std::vector<wxString>& aFieldsLabels,
const std::vector<wxString>& aFieldsShow,
const std::vector<wxString>& aFieldsGroupBy, const wxString& aSortField,
bool aSortAscending, const wxString& aFilterString, bool aGroupSymbols ) :
name( aName ),
readOnly( false ),
fields_show( aFieldsShow ),
fields_group_by( aFieldsGroupBy ),
column_widths( aColumnWidths ),
column_order( aColumnOrder ),
filter_string( aFilterString ),
group_symbols( aGroupSymbols )
fieldsOrdered( aFieldsOrdered ), fieldsLabels( aFieldsLabels ),
fieldsShow( aFieldsShow ), fieldsGroupBy( aFieldsGroupBy ), sortField( aSortField ),
sortAsc( aSortAscending ), filterString( aFilterString ), groupSymbols( aGroupSymbols )
{
}
wxString name;
bool readOnly;
std::map<std::string, bool> fields_show;
std::map<std::string, bool> fields_group_by;
std::map<std::string, int> column_widths;
std::vector<wxString> column_order;
wxString sort_field;
bool sort_asc;
wxString filter_string;
bool group_symbols;
bool readOnly = false;
std::vector<wxString> fieldsOrdered;
std::vector<wxString> fieldsLabels;
std::vector<wxString> fieldsShow;
std::vector<wxString> fieldsGroupBy;
wxString sortField;
bool sortAsc = true;
wxString filterString;
bool groupSymbols = false;
};
@ -71,21 +63,22 @@ struct BOM_FMT_PRESET
{
BOM_FMT_PRESET( const wxString& aName = wxEmptyString ) :
name( aName ), readOnly( false ), fieldDelimiter( wxS( "\"" ) ),
stringDelimiter( wxS( "," ) ), spacedRefs( false ), removeTabs( true ),
removeLineBreaks( true )
stringDelimiter( wxS( "\"" ) ), refDelimiter( "," ), refRangeDelimiter( "" ),
keepTabs( true ), keepLineBreaks( true )
{
}
BOM_FMT_PRESET( const wxString& aName, const wxString& aFieldDelimiter,
const wxString& aStringDelimiter, bool spacedRefs, bool removeTabs,
bool removeLineBreaks ) :
const wxString& aStringDelimiter, const wxString& aRefDelimiter,
const wxString& aRefRangeDelimiter, bool removeTabs, bool removeLineBreaks ) :
name( aName ),
readOnly( false ),
fieldDelimiter( aFieldDelimiter ),
stringDelimiter( aStringDelimiter ),
spacedRefs( spacedRefs ),
removeTabs( removeTabs ),
removeLineBreaks( removeLineBreaks )
refDelimiter( aRefDelimiter ),
refRangeDelimiter( aRefRangeDelimiter ),
keepTabs( removeTabs ),
keepLineBreaks( removeLineBreaks )
{
}
@ -93,9 +86,10 @@ struct BOM_FMT_PRESET
bool readOnly;
wxString fieldDelimiter;
wxString stringDelimiter;
bool spacedRefs;
bool removeTabs;
bool removeLineBreaks;
wxString refDelimiter;
wxString refRangeDelimiter;
bool keepTabs;
bool keepLineBreaks;
};
@ -158,10 +152,15 @@ public:
TEMPLATES m_TemplateFieldNames;
/// List of stored BOM presets
static BOM_PRESET bomPresetGroupedByValue;
static BOM_PRESET bomPresetGroupedByValueFootprint;
BOM_PRESET m_BomSettings;
std::vector<BOM_PRESET> m_BomPresets;
/// List of stored BOM format presets
static BOM_FMT_PRESET bomFmtPresetCSV;
static BOM_FMT_PRESET bomFmtPresetSemicolons;
static BOM_FMT_PRESET bomFmtPresetTSV;
BOM_FMT_PRESET m_BomFmtSettings;
std::vector<BOM_FMT_PRESET> m_BomFmtPresets;

View File

@ -46,6 +46,7 @@ set( KICAD_CLI_SRCS
cli/command_export_pcb_svg.cpp
cli/command_fp_export_svg.cpp
cli/command_fp_upgrade.cpp
cli/command_export_sch_bom.cpp
cli/command_export_sch_pythonbom.cpp
cli/command_export_sch_netlist.cpp
cli/command_export_sch_plot.cpp

View File

@ -0,0 +1,149 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Mike Williams <mike@mikebwilliams.com>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_sch_bom.h"
#include <cli/exit_codes.h>
#include "jobs/job_export_sch_bom.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <schematic_settings.h>
#include <macros.h>
CLI::EXPORT_SCH_BOM_COMMAND::EXPORT_SCH_BOM_COMMAND() : EXPORT_PCB_BASE_COMMAND( "bom" )
{
// Field output options
m_argParser.add_argument( ARG_FIELDS )
.help( UTF8STDSTR( _( ARG_FIELDS ) ) )
.default_value( std::string( "Reference,Value,Footprint,Quantity" ) );
m_argParser.add_argument( ARG_LABELS )
.help( UTF8STDSTR( _( ARG_LABELS_DESC ) ) )
.default_value( std::string( "Refs,Value,Footprint,Qty" ) );
m_argParser.add_argument( ARG_GROUP_BY )
.help( UTF8STDSTR( _( ARG_GROUP_BY_DESC ) ) )
.default_value( std::string( "Value,Footprint" ) );
m_argParser.add_argument( ARG_SORT_FIELD )
.help( UTF8STDSTR( _( ARG_SORT_FIELD_DESC ) ) )
.default_value( std::string( "Reference" ) );
m_argParser.add_argument( ARG_SORT_ASC )
.help( UTF8STDSTR( _( ARG_SORT_ASC_DESC ) ) )
.implicit_value( true )
.default_value( true );
m_argParser.add_argument( ARG_FILTER )
.help( UTF8STDSTR( _( ARG_FILTER_DESC ) ) )
.default_value( std::string( "" ) );
m_argParser.add_argument( ARG_GROUP_SYMBOLS )
.help( UTF8STDSTR( _( ARG_GROUP_SYMBOLS_DESC ) ) )
.implicit_value( true )
.default_value( true );
// Output formatting options
m_argParser.add_argument( ARG_FIELD_DELIMITER )
.help( UTF8STDSTR( _( ARG_FIELD_DELIMITER_DESC ) ) )
.default_value( std::string( "," ) );
m_argParser.add_argument( ARG_STRING_DELIMITER )
.help( UTF8STDSTR( _( ARG_STRING_DELIMITER_DESC ) ) )
.default_value( std::string( "\"" ) );
m_argParser.add_argument( ARG_REF_DELIMITER )
.help( UTF8STDSTR( _( ARG_REF_DELIMITER_DESC ) ) )
.default_value( std::string( "," ) );
m_argParser.add_argument( ARG_REF_RANGE_DELIMITER )
.help( UTF8STDSTR( _( ARG_REF_RANGE_DELIMITER_DESC ) ) )
.default_value( std::string( "-" ) );
m_argParser.add_argument( ARG_KEEP_TABS )
.help( UTF8STDSTR( _( ARG_KEEP_TABS_DESC ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_KEEP_LINE_BREAKS )
.help( UTF8STDSTR( _( ARG_KEEP_LINE_BREAKS_DESC ) ) )
.implicit_value( true )
.default_value( false );
}
std::vector<wxString> CLI::EXPORT_SCH_BOM_COMMAND::convertStringList( const wxString& aList )
{
std::vector<wxString> v;
if( !aList.IsEmpty() )
{
wxStringTokenizer layerTokens( aList, "," );
while( layerTokens.HasMoreTokens() )
v.emplace_back( layerTokens.GetNextToken() );
}
return v;
}
int CLI::EXPORT_SCH_BOM_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_SCH_BOM> bomJob = std::make_unique<JOB_EXPORT_SCH_BOM>( true );
// Basic options
bomJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
bomJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
// Format options
bomJob->m_fieldDelimiter =
FROM_UTF8( m_argParser.get<std::string>( ARG_FIELD_DELIMITER ).c_str() );
bomJob->m_stringDelimiter =
FROM_UTF8( m_argParser.get<std::string>( ARG_STRING_DELIMITER ).c_str() );
bomJob->m_refDelimiter = FROM_UTF8( m_argParser.get<std::string>( ARG_REF_DELIMITER ).c_str() );
bomJob->m_refRangeDelimiter =
FROM_UTF8( m_argParser.get<std::string>( ARG_REF_RANGE_DELIMITER ).c_str() );
bomJob->m_keepTabs = m_argParser.get<bool>( ARG_KEEP_TABS );
bomJob->m_keepLineBreaks = m_argParser.get<bool>( ARG_KEEP_LINE_BREAKS );
// Output fields options
bomJob->m_fieldsOrdered =
convertStringList( FROM_UTF8( m_argParser.get<std::string>( ARG_FIELDS ).c_str() ) );
bomJob->m_fieldsLabels =
convertStringList( FROM_UTF8( m_argParser.get<std::string>( ARG_LABELS ).c_str() ) );
bomJob->m_fieldsGroupBy =
convertStringList( FROM_UTF8( m_argParser.get<std::string>( ARG_GROUP_BY ).c_str() ) );
bomJob->m_sortField = FROM_UTF8( m_argParser.get<std::string>( ARG_SORT_FIELD ).c_str() );
bomJob->m_sortAsc = m_argParser.get<bool>( ARG_SORT_ASC );
bomJob->m_filterString = FROM_UTF8( m_argParser.get<std::string>( ARG_FILTER ).c_str() );
bomJob->m_groupSymbols = m_argParser.get<bool>( ARG_GROUP_SYMBOLS );
if( !wxFile::Exists( bomJob->m_filename ) )
{
wxFprintf( stderr, _( "Schematic file does not exist or is not accessible\n" ) );
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
int exitCode = aKiway.ProcessJob( KIWAY::FACE_SCH, bomJob.get() );
return exitCode;
}

View File

@ -0,0 +1,83 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Mike Williams <mike@mikebwilliams.com>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_SCH_BOM_H
#define COMMAND_EXPORT_SCH_BOM_H
#include "command_export_pcb_base.h"
namespace CLI
{
// Options for setting the format of the export, e.g. CSV
#define ARG_FIELD_DELIMITER "--field-delimiter"
#define ARG_FIELD_DELIMITER_DESC "Separator between output fields/columns."
#define ARG_STRING_DELIMITER "--string-delimiter"
#define ARG_STRING_DELIMITER_DESC "Character to surround fields with."
#define ARG_REF_DELIMITER "--ref-delimiter"
#define ARG_REF_DELIMITER_DESC "Character to place between individual references."
#define ARG_REF_RANGE_DELIMITER "--ref-range-delimiter"
#define ARG_REF_RANGE_DELIMITER_DESC "Character to place in ranges of references. Leave blank for no ranges."
#define ARG_KEEP_TABS "--keep-tabs"
#define ARG_KEEP_TABS_DESC "Keep tab characters from input fields. Stripped by default."
#define ARG_KEEP_LINE_BREAKS "--keep-newlines"
#define ARG_KEEP_LINE_BREAKS_DESC "Keep newline characters from input fields. Stripped by default."
//Options for controlling the fields and the grouping
#define ARG_FIELDS "--fields"
#define ARG_FIELDS_DESC "An ordered list of fields to export."
#define ARG_LABELS "--labels"
#define ARG_LABELS_DESC "An ordered list of labels to apply the exported fields."
#define ARG_GROUP_BY "--group-by"
#define ARG_GROUP_BY_DESC "Fields to group references by when field values match."
#define ARG_SORT_FIELD "--sort-field"
#define ARG_SORT_FIELD_DESC "Field name to sort by."
#define ARG_SORT_ASC "--sort-asc"
#define ARG_SORT_ASC_DESC "Sort ascending (true) or descending (false)."
#define ARG_FILTER "--filter"
#define ARG_FILTER_DESC "Filter string to remove output lines."
#define ARG_GROUP_SYMBOLS "--group"
#define ARG_GROUP_SYMBOLS_DESC "Enable grouping of references with matching group-by fields."
class EXPORT_SCH_BOM_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
public:
EXPORT_SCH_BOM_COMMAND();
protected:
int doPerform( KIWAY& aKiway ) override;
private:
std::vector<wxString> convertStringList( const wxString& aList );
};
} // namespace CLI
#endif

View File

@ -57,6 +57,7 @@
#include "cli/command_export_pcb_pos.h"
#include "cli/command_export_pcb_svg.h"
#include "cli/command_export_pcb_step.h"
#include "cli/command_export_sch_bom.h"
#include "cli/command_export_sch_pythonbom.h"
#include "cli/command_export_sch_netlist.h"
#include "cli/command_export_sch_plot.h"
@ -137,6 +138,7 @@ static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
static CLI::PCB_COMMAND pcbCmd{};
static CLI::EXPORT_SCH_COMMAND exportSchCmd{};
static CLI::SCH_COMMAND schCmd{};
static CLI::EXPORT_SCH_BOM_COMMAND exportSchBomCmd{};
static CLI::EXPORT_SCH_PYTHONBOM_COMMAND exportSchPythonBomCmd{};
static CLI::EXPORT_SCH_NETLIST_COMMAND exportSchNetlistCmd{};
static CLI::EXPORT_SCH_PLOT_COMMAND exportSchDxfCmd{ "dxf", PLOT_FORMAT::DXF };
@ -199,6 +201,7 @@ static std::vector<COMMAND_ENTRY> commandStack = {
&exportSchNetlistCmd,
&exportSchPdfCmd,
&exportSchPostscriptCmd,
&exportSchBomCmd,
&exportSchPythonBomCmd,
&exportSchSvgCmd
}