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::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent ) :
DIALOG_SYMBOL_FIELDS_TABLE_BASE( parent ), m_currentBomPreset( nullptr ), DIALOG_SYMBOL_FIELDS_TABLE_BASE( parent ), m_currentBomPreset( nullptr ),
m_lastSelectedBomPreset( nullptr ), m_parent( parent ), 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_fieldsCtrl->SetIndent( 0 );
m_filter->SetDescriptiveText( _( "Filter" ) ); 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 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->SetMinimumPaneSize( fieldsMinWidth );
m_splitterMainWindow->SetSashPosition( fieldsMinWidth + 40 ); 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->UseNativeColHeader( true );
m_grid->SetTable( m_dataModel, 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 // Load our BOM view presets
SetUserBomPresets( m_schSettings.m_BomPresets ); SetUserBomPresets( m_schSettings.m_BomPresets );
ApplyBomPreset( bomPresetGroupedByValueFootprint ); ApplyBomPreset( SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint );
syncBomPresetSelection(); syncBomPresetSelection();
// Load BOM export format presets // Load BOM export format presets
SetUserBomFmtPresets( m_schSettings.m_BomFmtPresets ); SetUserBomFmtPresets( m_schSettings.m_BomFmtPresets );
ApplyBomFmtPreset( bomFmtPresetCSV ); ApplyBomFmtPreset( SCHEMATIC_SETTINGS::bomFmtPresetCSV );
syncBomFmtPresetSelection(); syncBomFmtPresetSelection();
m_grid->SelectRow( 0 ); m_grid->SelectRow( 0 );
@ -377,11 +320,12 @@ void DIALOG_SYMBOL_FIELDS_TABLE::SetupColumnProperties()
// become unhidden. // become unhidden.
if( m_grid->IsColShown( col ) ) if( m_grid->IsColShown( col ) )
{ {
EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
std::string key( m_dataModel->GetColFieldName( col ).ToUTF8() ); 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 ); m_grid->SetColSize( col, width );
} }
else 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; 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(); 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 // Reset the view to where we left the user
m_parent->SetCurrentSheet( currentSheet ); m_parent->SetCurrentSheet( currentSheet );
@ -513,29 +463,20 @@ bool DIALOG_SYMBOL_FIELDS_TABLE::TransferDataFromWindow()
} }
void DIALOG_SYMBOL_FIELDS_TABLE::AddField( const wxString& aFieldName, void DIALOG_SYMBOL_FIELDS_TABLE::AddField( const wxString& aFieldName, const wxString& aLabelValue,
const wxString& aLabelValue, bool show, bool groupBy, bool addedByUser )
bool defaultShow, bool defaultSortBy, bool addedByUser )
{ {
m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser ); m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser );
wxVector<wxVariant> fieldsCtrlRow; wxVector<wxVariant> fieldsCtrlRow;
bool show = defaultShow;
bool sort_by = defaultSortBy;
std::string key( aFieldName.ToUTF8() ); 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 // Don't change these to emplace_back: some versions of wxWidgets don't support it
fieldsCtrlRow.push_back( wxVariant( aFieldName ) ); fieldsCtrlRow.push_back( wxVariant( aFieldName ) );
fieldsCtrlRow.push_back( wxVariant( aLabelValue ) ); fieldsCtrlRow.push_back( wxVariant( aLabelValue ) );
fieldsCtrlRow.push_back( wxVariant( show ) ); fieldsCtrlRow.push_back( wxVariant( show ) );
fieldsCtrlRow.push_back( wxVariant( sort_by ) ); fieldsCtrlRow.push_back( wxVariant( groupBy ) );
fieldsCtrlRow.push_back( wxVariant( aFieldName ) ); fieldsCtrlRow.push_back( wxVariant( aFieldName ) );
m_fieldsCtrl->AppendItem( fieldsCtrlRow ); m_fieldsCtrl->AppendItem( fieldsCtrlRow );
@ -622,7 +563,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnAddField( wxCommandEvent& event )
std::string key( fieldName.ToUTF8() ); 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 ); AddField( fieldName, fieldName, true, false, true );
wxGridTableMessage msg( m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 ); 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_dataModel->RenameColumn( col, newFieldName );
m_fieldsCtrl->SetTextValue( newFieldName, col, 0 ); 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(); syncBomPresetSelection();
} }
void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterText( wxCommandEvent& aEvent ) 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->SetFilter( m_filter->GetValue() );
m_dataModel->RebuildRows(); m_dataModel->RebuildRows();
m_grid->ForceRefresh(); m_grid->ForceRefresh();
@ -804,11 +737,9 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
case SHOW_FIELD_COLUMN: case SHOW_FIELD_COLUMN:
{ {
bool value = m_fieldsCtrl->GetToggleValue( row, col ); 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 ); m_dataModel->SetShowColumn( dataCol, value );
if( dataCol != -1 ) if( dataCol != -1 )
@ -834,9 +765,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
m_fieldsCtrl->SetToggleValue( value, row, col ); m_fieldsCtrl->SetToggleValue( value, row, col );
} }
wxString fieldName = m_fieldsCtrl->GetTextValue( row, FIELD_NAME_COLUMN ); 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->SetGroupColumn( m_dataModel->GetFieldNameCol( fieldName ), value );
m_dataModel->RebuildRows(); m_dataModel->RebuildRows();
@ -854,7 +783,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColumnItemToggled( wxDataViewEvent& event )
void DIALOG_SYMBOL_FIELDS_TABLE::OnGroupSymbolsToggled( wxCommandEvent& 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->SetGroupingEnabled( m_groupSymbolsBox->GetValue() );
m_dataModel->RebuildRows(); m_dataModel->RebuildRows();
m_grid->ForceRefresh(); 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 // We only support sorting on one column at this time
m_schSettings.m_BomSettings.sort_field = m_dataModel->GetColFieldName( sortCol ); m_schSettings.m_BomSettings.sortField = m_dataModel->GetColFieldName( sortCol );
m_schSettings.m_BomSettings.sort_asc = ascending; m_schSettings.m_BomSettings.sortAsc = ascending;
m_dataModel->SetSorting( sortCol, ascending ); m_dataModel->SetSorting( sortCol, ascending );
m_dataModel->RebuildRows(); m_dataModel->RebuildRows();
@ -905,7 +834,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnColMove( wxGridEvent& aEvent )
m_dataModel->MoveColumn( origPos, newPos ); 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 // "Unmove" the column since we've moved the column internally
m_grid->ResetColPos(); m_grid->ResetColPos();
@ -949,9 +878,6 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnTableColSize( wxGridSizeEvent& aEvent )
int col = aEvent.GetRowOrCol(); int col = aEvent.GetRowOrCol();
std::string key( m_dataModel->GetColFieldName( col ).ToUTF8() ); 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(); aEvent.Skip();
m_grid->ForceRefresh(); m_grid->ForceRefresh();
@ -1074,9 +1000,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::PreviewRefresh()
current.fieldDelimiter = m_textFieldDelimiter->GetValue(); current.fieldDelimiter = m_textFieldDelimiter->GetValue();
current.stringDelimiter = m_textStringDelimiter->GetValue(); current.stringDelimiter = m_textStringDelimiter->GetValue();
current.spacedRefs = m_checkSpacedRefs->GetValue(); current.refDelimiter = m_textRefDelimiter->GetValue();
current.removeTabs = m_checkRemoveTabs->GetValue(); current.refRangeDelimiter = m_textRefRangeDelimiter->GetValue();
current.removeLineBreaks = m_checkRemoveLineBreaks->GetValue(); current.keepTabs = m_checkKeepTabs->GetValue();
current.keepLineBreaks = m_checkKeepLineBreaks->GetValue();
m_textOutput->SetValue( m_dataModel->Export( current ) ); m_textOutput->SetValue( m_dataModel->Export( current ) );
} }
@ -1274,7 +1201,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::loadDefaultBomPresets()
m_bomPresetMRU.clear(); m_bomPresetMRU.clear();
// Load the read-only defaults // 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] = preset;
m_bomPresets[preset.name].readOnly = true; m_bomPresets[preset.name].readOnly = true;
@ -1298,7 +1226,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::rebuildBomPresetsWidget()
m_cbBomPresets->Append( wxGetTranslation( pair.first ), m_cbBomPresets->Append( wxGetTranslation( pair.first ),
static_cast<void*>( &pair.second ) ); static_cast<void*>( &pair.second ) );
if( pair.first == bomPresetGroupedByValueFootprint.name ) if( pair.first == SCHEMATIC_SETTINGS::bomPresetGroupedByValueFootprint.name )
default_idx = idx; default_idx = idx;
idx++; idx++;
@ -1324,13 +1252,15 @@ void DIALOG_SYMBOL_FIELDS_TABLE::syncBomPresetSelection()
auto it = std::find_if( m_bomPresets.begin(), m_bomPresets.end(), auto it = std::find_if( m_bomPresets.begin(), m_bomPresets.end(),
[&]( const std::pair<const wxString, BOM_PRESET>& aPair ) [&]( const std::pair<const wxString, BOM_PRESET>& aPair )
{ {
return ( aPair.second.fields_show == current.fields_show return ( aPair.second.fieldsOrdered == current.fieldsOrdered
&& aPair.second.fields_group_by == current.fields_group_by && aPair.second.fieldsLabels == current.fieldsLabels
&& aPair.second.sort_field == current.sort_field && aPair.second.fieldsShow == current.fieldsShow
&& aPair.second.sort_asc == current.sort_asc && aPair.second.fieldsGroupBy == current.fieldsGroupBy
&& aPair.second.column_order == current.column_order && aPair.second.sortField == current.sortField
&& aPair.second.filter_string == current.filter_string && aPair.second.sortAsc == current.sortAsc
&& aPair.second.group_symbols == current.group_symbols ); && aPair.second.fieldsOrdered == current.fieldsOrdered
&& aPair.second.filterString == current.filterString
&& aPair.second.groupSymbols == current.groupSymbols );
} ); } );
if( it != m_bomPresets.end() ) if( it != m_bomPresets.end() )
@ -1426,14 +1356,14 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomPresetChanged( wxCommandEvent& aEvent )
if( !exists ) if( !exists )
{ {
m_bomPresets[name] = BOM_PRESET( name, m_schSettings.m_BomSettings.fields_show, m_bomPresets[name] = BOM_PRESET( name, m_schSettings.m_BomSettings.fieldsOrdered,
m_schSettings.m_BomSettings.fields_group_by, m_schSettings.m_BomSettings.fieldsLabels,
m_schSettings.m_BomSettings.column_widths, m_schSettings.m_BomSettings.fieldsShow,
m_schSettings.m_BomSettings.column_order, m_schSettings.m_BomSettings.fieldsGroupBy,
m_schSettings.m_BomSettings.sort_field, m_schSettings.m_BomSettings.sortField,
m_schSettings.m_BomSettings.sort_asc, m_schSettings.m_BomSettings.sortAsc,
m_schSettings.m_BomSettings.filter_string, m_schSettings.m_BomSettings.filterString,
m_schSettings.m_BomSettings.group_symbols ); m_schSettings.m_BomSettings.groupSymbols );
} }
BOM_PRESET* preset = &m_bomPresets[name]; BOM_PRESET* preset = &m_bomPresets[name];
@ -1445,14 +1375,14 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomPresetChanged( wxCommandEvent& aEvent )
} }
else else
{ {
preset->fields_show = m_schSettings.m_BomSettings.fields_show; preset->fieldsOrdered = m_schSettings.m_BomSettings.fieldsOrdered;
preset->fields_group_by = m_schSettings.m_BomSettings.fields_group_by; preset->fieldsLabels = m_schSettings.m_BomSettings.fieldsLabels;
preset->column_widths = m_schSettings.m_BomSettings.column_widths; preset->fieldsShow = m_schSettings.m_BomSettings.fieldsShow;
preset->column_order = m_schSettings.m_BomSettings.column_order; preset->fieldsGroupBy = m_schSettings.m_BomSettings.fieldsGroupBy;
preset->sort_field = m_schSettings.m_BomSettings.sort_field; preset->sortField = m_schSettings.m_BomSettings.sortField;
preset->sort_asc = m_schSettings.m_BomSettings.sort_asc; preset->sortAsc = m_schSettings.m_BomSettings.sortAsc;
preset->filter_string = m_schSettings.m_BomSettings.filter_string; preset->filterString = m_schSettings.m_BomSettings.filterString;
preset->group_symbols = m_schSettings.m_BomSettings.group_symbols; preset->groupSymbols = m_schSettings.m_BomSettings.groupSymbols;
index = m_cbBomPresets->FindString( name ); index = m_cbBomPresets->FindString( name );
m_bomPresetMRU.Remove( 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 ) void DIALOG_SYMBOL_FIELDS_TABLE::doApplyBomPreset( const BOM_PRESET& aPreset )
{ {
// Set a good default sort // Basically, we apply the BOM preset to the data model and then
int refCol = m_dataModel->GetFieldNameCol( // update our UI to reflect resulting the data model state, not the preset.
TEMPLATE_FIELDNAME::GetDefaultFieldName( REFERENCE_FIELD ) ); m_dataModel->ApplyBomPreset( aPreset );
m_grid->SetSortingColumn( refCol, false );
// 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++ ) 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 ); int col = m_dataModel->GetFieldNameCol( fieldName );
if( col == -1 ) if( col == -1 )
{
wxASSERT_MSG( true, "Fields control has a field not found in the data model." );
continue; continue;
}
bool show = aPreset.fields_show.count( fieldName ) && aPreset.fields_show.at( fieldName ); EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
bool groupBy = aPreset.fields_group_by.count( fieldName ) std::string fieldNameStr( fieldName.ToUTF8() );
&& aPreset.fields_group_by.at( fieldName );
int width = aPreset.column_widths.count( fieldName ) ? aPreset.column_widths.at( fieldName ) if( cfg->m_FieldEditorPanel.field_widths.count( fieldNameStr ) )
: -1; m_grid->SetColMinimalWidth( col,
cfg->m_FieldEditorPanel.field_widths.at( fieldNameStr ) );
// Set shown colums // Set shown colums
bool show = m_dataModel->GetShowColumn( col );
m_fieldsCtrl->SetToggleValue( show, i, SHOW_FIELD_COLUMN ); m_fieldsCtrl->SetToggleValue( show, i, SHOW_FIELD_COLUMN );
m_dataModel->SetShowColumn( col, show );
if( show ) if( show )
{
m_grid->ShowCol( col ); m_grid->ShowCol( col );
//m_grid->SetColSize( col, schSettings. );
}
else else
m_grid->HideCol( col ); m_grid->HideCol( col );
// Set grouped columns // Set grouped columns
bool groupBy = m_dataModel->GetGroupColumn( col );
m_fieldsCtrl->SetToggleValue( groupBy, i, GROUP_BY_COLUMN ); 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_grid->SetSortingColumn( m_dataModel->GetSortCol(), m_dataModel->GetSortAsc() );
m_groupSymbolsBox->SetValue( aPreset.group_symbols ); m_groupSymbolsBox->SetValue( m_dataModel->GetGroupingEnabled() );
m_filter->ChangeValue( m_dataModel->GetFilter() );
m_dataModel->SetFieldsOrder( aPreset.column_order );
m_dataModel->SetFilter( aPreset.filter_string );
m_filter->ChangeValue( aPreset.filter_string );
SetupColumnProperties(); 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_dataModel->RebuildRows();
m_grid->ForceRefresh(); m_grid->ForceRefresh();
m_schSettings.m_BomSettings.fields_show = aPreset.fields_show; m_schSettings.m_BomSettings = aPreset;
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;
} }
@ -1659,7 +1597,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::loadDefaultBomFmtPresets()
// Load the read-only defaults // Load the read-only defaults
for( const BOM_FMT_PRESET& preset : 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] = preset;
m_bomFmtPresets[preset.name].readOnly = true; m_bomFmtPresets[preset.name].readOnly = true;
@ -1683,7 +1622,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::rebuildBomFmtPresetsWidget()
m_cbBomFmtPresets->Append( wxGetTranslation( pair.first ), m_cbBomFmtPresets->Append( wxGetTranslation( pair.first ),
static_cast<void*>( &pair.second ) ); static_cast<void*>( &pair.second ) );
if( pair.first == bomFmtPresetCSV.name ) if( pair.first == SCHEMATIC_SETTINGS::bomFmtPresetCSV.name )
default_idx = idx; default_idx = idx;
idx++; idx++;
@ -1712,9 +1651,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::syncBomFmtPresetSelection()
{ {
return ( aPair.second.fieldDelimiter == current.fieldDelimiter return ( aPair.second.fieldDelimiter == current.fieldDelimiter
&& aPair.second.stringDelimiter == current.stringDelimiter && aPair.second.stringDelimiter == current.stringDelimiter
&& aPair.second.spacedRefs == current.spacedRefs && aPair.second.refDelimiter == current.refDelimiter
&& aPair.second.removeTabs == current.removeTabs && aPair.second.refRangeDelimiter == current.refRangeDelimiter
&& aPair.second.removeLineBreaks == current.removeLineBreaks ); && aPair.second.keepTabs == current.keepTabs
&& aPair.second.keepLineBreaks == current.keepLineBreaks );
} ); } );
if( it != m_bomFmtPresets.end() ) if( it != m_bomFmtPresets.end() )
@ -1811,12 +1751,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::onBomFmtPresetChanged( wxCommandEvent& aEvent )
if( !exists ) if( !exists )
{ {
m_bomFmtPresets[name] = BOM_FMT_PRESET( name, m_bomFmtPresets[name] =
m_schSettings.m_BomFmtSettings.fieldDelimiter, BOM_FMT_PRESET( name, m_schSettings.m_BomFmtSettings.fieldDelimiter,
m_schSettings.m_BomFmtSettings.stringDelimiter, m_schSettings.m_BomFmtSettings.stringDelimiter,
m_schSettings.m_BomFmtSettings.spacedRefs, m_schSettings.m_BomFmtSettings.refDelimiter,
m_schSettings.m_BomFmtSettings.removeTabs, m_schSettings.m_BomFmtSettings.refRangeDelimiter,
m_schSettings.m_BomFmtSettings.removeLineBreaks ); m_schSettings.m_BomFmtSettings.keepTabs,
m_schSettings.m_BomFmtSettings.keepLineBreaks );
} }
BOM_FMT_PRESET* preset = &m_bomFmtPresets[name]; 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->fieldDelimiter = m_schSettings.m_BomFmtSettings.fieldDelimiter;
preset->stringDelimiter = m_schSettings.m_BomFmtSettings.stringDelimiter; preset->stringDelimiter = m_schSettings.m_BomFmtSettings.stringDelimiter;
preset->spacedRefs = m_schSettings.m_BomFmtSettings.spacedRefs; preset->refDelimiter = m_schSettings.m_BomFmtSettings.refDelimiter;
preset->removeTabs = m_schSettings.m_BomFmtSettings.removeTabs; preset->refRangeDelimiter = m_schSettings.m_BomFmtSettings.refRangeDelimiter;
preset->removeLineBreaks = m_schSettings.m_BomFmtSettings.removeLineBreaks; preset->keepTabs = m_schSettings.m_BomFmtSettings.keepTabs;
preset->keepLineBreaks = m_schSettings.m_BomFmtSettings.keepLineBreaks;
index = m_cbBomFmtPresets->FindString( name ); index = m_cbBomFmtPresets->FindString( name );
m_bomFmtPresetMRU.Remove( 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_textFieldDelimiter->ChangeValue( aPreset.fieldDelimiter );
m_textStringDelimiter->ChangeValue( aPreset.stringDelimiter ); m_textStringDelimiter->ChangeValue( aPreset.stringDelimiter );
m_checkSpacedRefs->SetValue( aPreset.spacedRefs ); m_textRefDelimiter->SetValue( aPreset.refDelimiter );
m_checkRemoveTabs->SetValue( aPreset.removeTabs ); m_textRefRangeDelimiter->SetValue( aPreset.refRangeDelimiter );
m_checkRemoveLineBreaks->SetValue( aPreset.removeLineBreaks ); m_checkKeepTabs->SetValue( aPreset.keepTabs );
m_checkKeepLineBreaks->SetValue( aPreset.keepLineBreaks );
PreviewRefresh(); PreviewRefresh();
m_schSettings.m_BomFmtSettings.fieldDelimiter = aPreset.fieldDelimiter; m_schSettings.m_BomFmtSettings.fieldDelimiter = aPreset.fieldDelimiter;
m_schSettings.m_BomFmtSettings.stringDelimiter = aPreset.stringDelimiter; m_schSettings.m_BomFmtSettings.stringDelimiter = aPreset.stringDelimiter;
m_schSettings.m_BomFmtSettings.spacedRefs = aPreset.spacedRefs; m_schSettings.m_BomFmtSettings.refDelimiter = aPreset.refDelimiter;
m_schSettings.m_BomFmtSettings.removeTabs = aPreset.removeTabs; m_schSettings.m_BomFmtSettings.refRangeDelimiter = aPreset.refRangeDelimiter;
m_schSettings.m_BomFmtSettings.removeLineBreaks = aPreset.removeLineBreaks; m_schSettings.m_BomFmtSettings.keepTabs = aPreset.keepTabs;
m_schSettings.m_BomFmtSettings.keepLineBreaks = aPreset.keepLineBreaks;
} }

View File

@ -48,8 +48,8 @@ public:
private: private:
void SetupColumnProperties(); void SetupColumnProperties();
void AddField( const wxString& displayName, const wxString& aCanonicalName, bool defaultShow, void AddField( const wxString& displayName, const wxString& aCanonicalName, bool show,
bool defaultSortBy, bool addedByUser = false ); bool groupBy, bool addedByUser = false );
/** /**
* Construct the rows of m_fieldsCtrl and the columns of m_dataModel from a union of all * 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; BOM_PRESET* m_lastSelectedBomPreset;
wxArrayString m_bomPresetMRU; wxArrayString m_bomPresetMRU;
static BOM_PRESET bomPresetGroupedByValue;
static BOM_PRESET bomPresetGroupedByValueFootprint;
void syncBomFmtPresetSelection(); void syncBomFmtPresetSelection();
void rebuildBomFmtPresetsWidget(); void rebuildBomFmtPresetsWidget();
void updateBomFmtPresetSelection( const wxString& aName ); void updateBomFmtPresetSelection( const wxString& aName );
@ -124,10 +121,6 @@ private:
BOM_FMT_PRESET* m_lastSelectedBomFmtPreset; BOM_FMT_PRESET* m_lastSelectedBomFmtPreset;
wxArrayString m_bomFmtPresetMRU; wxArrayString m_bomFmtPresetMRU;
static BOM_FMT_PRESET bomFmtPresetCSV;
static BOM_FMT_PRESET bomFmtPresetSemicolons;
static BOM_FMT_PRESET bomFmtPresetTSV;
SCH_EDIT_FRAME* m_parent; SCH_EDIT_FRAME* m_parent;
int m_fieldNameColWidth; int m_fieldNameColWidth;
int m_labelColWidth; 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 ); gbExport->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxFlexGridSizer* fgExportOptions; wxFlexGridSizer* fgExportOptions;
fgExportOptions = new wxFlexGridSizer( 6, 2, 0, 0 ); fgExportOptions = new wxFlexGridSizer( 7, 2, 0, 0 );
fgExportOptions->AddGrowableRow( 5 );
fgExportOptions->SetFlexibleDirection( wxBOTH ); fgExportOptions->SetFlexibleDirection( wxBOTH );
fgExportOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); 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 ); m_textStringDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _("\""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
fgExportOptions->Add( m_textStringDelimiter, 0, wxALL|wxEXPAND, 5 ); fgExportOptions->Add( m_textStringDelimiter, 0, wxALL|wxEXPAND, 5 );
m_labelSpacedRefs = new wxStaticText( m_panelExport, wxID_ANY, _("Spaced References:"), wxDefaultPosition, wxDefaultSize, 0 ); m_labelRefDelimiter = new wxStaticText( m_panelExport, wxID_ANY, _("Reference Delimiter:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSpacedRefs->Wrap( -1 ); m_labelRefDelimiter->Wrap( -1 );
fgExportOptions->Add( m_labelSpacedRefs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); fgExportOptions->Add( m_labelRefDelimiter, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkSpacedRefs = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_textRefDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _(","), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
fgExportOptions->Add( m_checkSpacedRefs, 0, wxALL, 5 ); fgExportOptions->Add( m_textRefDelimiter, 0, wxALL, 5 );
m_labelRemoveTabs = new wxStaticText( m_panelExport, wxID_ANY, _("Remove Tabs:"), wxDefaultPosition, wxDefaultSize, 0 ); m_labelRefRangeDelimiter = new wxStaticText( m_panelExport, wxID_ANY, _("Range Delimiter:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelRemoveTabs->Wrap( -1 ); m_labelRefRangeDelimiter->Wrap( -1 );
fgExportOptions->Add( m_labelRemoveTabs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); 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_textRefRangeDelimiter = new wxTextCtrl( m_panelExport, wxID_ANY, _("-"), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB );
m_checkRemoveTabs->SetValue(true); m_textRefRangeDelimiter->SetToolTip( _("Leave blank to disable ranges.") );
fgExportOptions->Add( m_checkRemoveTabs, 0, wxALL, 5 );
m_labelRemoveLineBreaks = new wxStaticText( m_panelExport, wxID_ANY, _("Remove Line Breaks:"), wxDefaultPosition, wxDefaultSize, 0 ); fgExportOptions->Add( m_textRefRangeDelimiter, 0, wxALL, 5 );
m_labelRemoveLineBreaks->Wrap( -1 );
fgExportOptions->Add( m_labelRemoveLineBreaks, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_checkRemoveLineBreaks = new wxCheckBox( m_panelExport, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_labelKeepTabs = new wxStaticText( m_panelExport, wxID_ANY, _("Keep Tabs:"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkRemoveLineBreaks->SetValue(true); m_labelKeepTabs->Wrap( -1 );
fgExportOptions->Add( m_checkRemoveLineBreaks, 0, wxALL, 5 ); 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 ); 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_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_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_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_textRefDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, 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_textRefRangeDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, 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_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_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_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 ); 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_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_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_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_textRefDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, 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_textRefRangeDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, 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_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_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_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 ); 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="cols">2</property>
<property name="flexible_direction">wxBOTH</property> <property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property> <property name="growablecols"></property>
<property name="growablerows">5</property> <property name="growablerows"></property>
<property name="hgap">0</property> <property name="hgap">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">fgExportOptions</property> <property name="name">fgExportOptions</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property> <property name="permission">none</property>
<property name="rows">6</property> <property name="rows">7</property>
<property name="vgap">0</property> <property name="vgap">0</property>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
@ -1853,7 +1853,7 @@
<property name="gripper">0</property> <property name="gripper">0</property>
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id">wxID_ANY</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="markup">0</property>
<property name="max_size"></property> <property name="max_size"></property>
<property name="maximize_button">0</property> <property name="maximize_button">0</property>
@ -1862,7 +1862,259 @@
<property name="minimize_button">0</property> <property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</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_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>
@ -1923,7 +2175,7 @@
<property name="minimize_button">0</property> <property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</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_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>
@ -1979,7 +2231,7 @@
<property name="gripper">0</property> <property name="gripper">0</property>
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id">wxID_ANY</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="markup">0</property>
<property name="max_size"></property> <property name="max_size"></property>
<property name="maximize_button">0</property> <property name="maximize_button">0</property>
@ -1988,7 +2240,7 @@
<property name="minimize_button">0</property> <property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</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_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>
@ -2026,7 +2278,7 @@
<property name="caption"></property> <property name="caption"></property>
<property name="caption_visible">1</property> <property name="caption_visible">1</property>
<property name="center_pane">0</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="close_button">1</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
@ -2049,133 +2301,7 @@
<property name="minimize_button">0</property> <property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</property> <property name="moveable">1</property>
<property name="name">m_checkRemoveTabs</property> <property name="name">m_checkKeepLineBreaks</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="pane_border">1</property> <property name="pane_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>

View File

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

View File

@ -22,6 +22,7 @@
#include <pgm_base.h> #include <pgm_base.h>
#include <cli/exit_codes.h> #include <cli/exit_codes.h>
#include <sch_plotter.h> #include <sch_plotter.h>
#include <jobs/job_export_sch_bom.h>
#include <jobs/job_export_sch_pythonbom.h> #include <jobs/job_export_sch_pythonbom.h>
#include <jobs/job_export_sch_netlist.h> #include <jobs/job_export_sch_netlist.h>
#include <jobs/job_export_sch_plot.h> #include <jobs/job_export_sch_plot.h>
@ -55,9 +56,13 @@
#include <netlist_exporter_kicad.h> #include <netlist_exporter_kicad.h>
#include <netlist_exporter_xml.h> #include <netlist_exporter_xml.h>
#include <fields_data_model.h>
EESCHEMA_JOBS_HANDLER::EESCHEMA_JOBS_HANDLER() EESCHEMA_JOBS_HANDLER::EESCHEMA_JOBS_HANDLER()
{ {
Register( "bom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ) );
Register( "pythonbom", Register( "pythonbom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ) ); std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ) );
Register( "netlist", 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 ) int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
{ {
JOB_EXPORT_SCH_PYTHONBOM* aNetJob = dynamic_cast<JOB_EXPORT_SCH_PYTHONBOM*>( 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: public:
EESCHEMA_JOBS_HANDLER(); EESCHEMA_JOBS_HANDLER();
int JobExportBom( JOB* aJob );
int JobExportPythonBom( JOB* aJob ); int JobExportPythonBom( JOB* aJob );
int JobExportNetlist( JOB* aJob ); int JobExportNetlist( JOB* aJob );
int JobExportPlot( JOB* aJob ); int JobExportPlot( JOB* aJob );
@ -73,4 +74,4 @@ public:
}; };
#endif #endif

View File

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

View File

@ -3,7 +3,7 @@
#include <wx/grid.h> #include <wx/grid.h>
#include <widgets/wx_grid.h> #include <widgets/wx_grid.h>
#include <sch_reference_list.h> #include <sch_reference_list.h>
#include <sch_edit_frame.h> #include <schematic_settings.h>
#include "string_utils.h" #include "string_utils.h"
#include "fields_data_model.h" #include "fields_data_model.h"
@ -12,6 +12,10 @@
void FIELDS_EDITOR_GRID_DATA_MODEL::AddColumn( const wxString& aFieldName, const wxString& aLabel, void FIELDS_EDITOR_GRID_DATA_MODEL::AddColumn( const wxString& aFieldName, const wxString& aLabel,
bool aAddedByUser ) bool aAddedByUser )
{ {
// Don't add a field twice
if( GetFieldNameCol( aFieldName ) != -1 )
return;
m_cols.push_back((struct DATA_MODEL_COL) { m_cols.push_back((struct DATA_MODEL_COL) {
.m_fieldName = aFieldName, .m_fieldName = aFieldName,
.m_label = aLabel, .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, 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; std::vector<SCH_REFERENCE> references;
wxString fieldValue; wxString fieldValue;
@ -183,7 +188,7 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::GetValue( const DATA_MODEL_ROW& group, i
} }
if( ColIsReference( aCol ) ) if( ColIsReference( aCol ) )
fieldValue = SCH_REFERENCE_LIST::Shorthand( references, spacedRefs ); fieldValue = SCH_REFERENCE_LIST::Shorthand( references, refDelimiter, refRangeDelimiter );
else if( ColIsQuantity( aCol ) ) else if( ColIsQuantity( aCol ) )
fieldValue = wxString::Format( wxT( "%d" ), (int) references.size() ); 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 ) for( unsigned i = 0; i < m_symbolsList.GetCount(); ++i )
{ {
SCH_SYMBOL& symbol = *m_symbolsList[i].GetSymbol(); 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]; 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 FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings )
{ {
wxString out; wxString out;
if( m_cols.empty() )
return out;
size_t last_col = m_cols.size() - 1; size_t last_col = m_cols.size() - 1;
// Find the location for the line terminator // 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 auto formatField = [&]( wxString field, bool last ) -> wxString
{ {
if( settings.removeLineBreaks ) if( !settings.keepLineBreaks )
{ {
field.Replace( wxS( "\r" ), wxS( "" ) ); field.Replace( wxS( "\r" ), wxS( "" ) );
field.Replace( wxS( "\n" ), wxS( "" ) ); field.Replace( wxS( "\n" ), wxS( "" ) );
} }
if( settings.removeTabs ) if( !settings.keepTabs )
{ {
field.Replace( wxS( "\t" ), wxS( "" ) ); field.Replace( wxS( "\t" ), wxS( "" ) );
} }
@ -642,7 +704,8 @@ wxString FIELDS_EDITOR_GRID_DATA_MODEL::Export( const BOM_FMT_PRESET& settings )
continue; continue;
// Get the unanottated version of the field, e.g. no "> " or "v " by // 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 ) ); col == last_col ) );
} }
} }

View File

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

View File

@ -587,7 +587,8 @@ public:
* "R1, R2, R4 - R7, U1" * "R1, R2, R4 - R7, U1"
* @param spaced Add spaces between references * @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; friend class BACK_ANNOTATION;

View File

@ -30,11 +30,42 @@
#include <settings/parameters.h> #include <settings/parameters.h>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
#include <sim/spice_settings.h> #include <sim/spice_settings.h>
#include <i18n_utility.h>
const int schSettingsSchemaVersion = 1; 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 ) : SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "schematic", schSettingsSchemaVersion, aParent, aPath ), NESTED_SETTINGS( "schematic", schSettingsSchemaVersion, aParent, aPath ),
m_DefaultLineWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS ), m_DefaultLineWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS ),

View File

@ -20,6 +20,8 @@
#ifndef KICAD_SCHEMATIC_SETTINGS_H #ifndef KICAD_SCHEMATIC_SETTINGS_H
#define KICAD_SCHEMATIC_SETTINGS_H #define KICAD_SCHEMATIC_SETTINGS_H
#include <set>
#include <default_values.h> #include <default_values.h>
#include <settings/nested_settings.h> #include <settings/nested_settings.h>
#include <template_fieldnames.h> #include <template_fieldnames.h>
@ -30,40 +32,30 @@ class NGSPICE_SIMULATOR_SETTINGS;
struct BOM_PRESET struct BOM_PRESET
{ {
BOM_PRESET( const wxString& aName = wxEmptyString ) : BOM_PRESET( const wxString& aName = wxEmptyString ) : name( aName ) {}
name( aName ), readOnly(false), sort_asc( true ), group_symbols( false) { }
BOM_PRESET( const wxString& aName, BOM_PRESET( const wxString& aName, const std::vector<wxString>& aFieldsOrdered,
const std::map<std::string, bool>& aFieldsShow, const std::vector<wxString>& aFieldsLabels,
const std::map<std::string, bool>& aFieldsGroupBy, const std::vector<wxString>& aFieldsShow,
const std::map<std::string, int>& aColumnWidths, const std::vector<wxString>& aFieldsGroupBy, const wxString& aSortField,
const std::vector<wxString>& aColumnOrder, bool aSortAscending, const wxString& aFilterString, bool aGroupSymbols ) :
const wxString& aSortField,
bool aSortAscending,
const wxString& aFilterString,
bool aGroupSymbols
) :
name( aName ), name( aName ),
readOnly( false ), fieldsOrdered( aFieldsOrdered ), fieldsLabels( aFieldsLabels ),
fields_show( aFieldsShow ), fieldsShow( aFieldsShow ), fieldsGroupBy( aFieldsGroupBy ), sortField( aSortField ),
fields_group_by( aFieldsGroupBy ), sortAsc( aSortAscending ), filterString( aFilterString ), groupSymbols( aGroupSymbols )
column_widths( aColumnWidths ),
column_order( aColumnOrder ),
filter_string( aFilterString ),
group_symbols( aGroupSymbols )
{ {
} }
wxString name; wxString name;
bool readOnly; bool readOnly = false;
std::map<std::string, bool> fields_show; std::vector<wxString> fieldsOrdered;
std::map<std::string, bool> fields_group_by; std::vector<wxString> fieldsLabels;
std::map<std::string, int> column_widths; std::vector<wxString> fieldsShow;
std::vector<wxString> column_order; std::vector<wxString> fieldsGroupBy;
wxString sort_field; wxString sortField;
bool sort_asc; bool sortAsc = true;
wxString filter_string; wxString filterString;
bool group_symbols; bool groupSymbols = false;
}; };
@ -71,21 +63,22 @@ struct BOM_FMT_PRESET
{ {
BOM_FMT_PRESET( const wxString& aName = wxEmptyString ) : BOM_FMT_PRESET( const wxString& aName = wxEmptyString ) :
name( aName ), readOnly( false ), fieldDelimiter( wxS( "\"" ) ), name( aName ), readOnly( false ), fieldDelimiter( wxS( "\"" ) ),
stringDelimiter( wxS( "," ) ), spacedRefs( false ), removeTabs( true ), stringDelimiter( wxS( "\"" ) ), refDelimiter( "," ), refRangeDelimiter( "" ),
removeLineBreaks( true ) keepTabs( true ), keepLineBreaks( true )
{ {
} }
BOM_FMT_PRESET( const wxString& aName, const wxString& aFieldDelimiter, BOM_FMT_PRESET( const wxString& aName, const wxString& aFieldDelimiter,
const wxString& aStringDelimiter, bool spacedRefs, bool removeTabs, const wxString& aStringDelimiter, const wxString& aRefDelimiter,
bool removeLineBreaks ) : const wxString& aRefRangeDelimiter, bool removeTabs, bool removeLineBreaks ) :
name( aName ), name( aName ),
readOnly( false ), readOnly( false ),
fieldDelimiter( aFieldDelimiter ), fieldDelimiter( aFieldDelimiter ),
stringDelimiter( aStringDelimiter ), stringDelimiter( aStringDelimiter ),
spacedRefs( spacedRefs ), refDelimiter( aRefDelimiter ),
removeTabs( removeTabs ), refRangeDelimiter( aRefRangeDelimiter ),
removeLineBreaks( removeLineBreaks ) keepTabs( removeTabs ),
keepLineBreaks( removeLineBreaks )
{ {
} }
@ -93,9 +86,10 @@ struct BOM_FMT_PRESET
bool readOnly; bool readOnly;
wxString fieldDelimiter; wxString fieldDelimiter;
wxString stringDelimiter; wxString stringDelimiter;
bool spacedRefs; wxString refDelimiter;
bool removeTabs; wxString refRangeDelimiter;
bool removeLineBreaks; bool keepTabs;
bool keepLineBreaks;
}; };
@ -158,10 +152,15 @@ public:
TEMPLATES m_TemplateFieldNames; TEMPLATES m_TemplateFieldNames;
/// List of stored BOM presets /// List of stored BOM presets
static BOM_PRESET bomPresetGroupedByValue;
static BOM_PRESET bomPresetGroupedByValueFootprint;
BOM_PRESET m_BomSettings; BOM_PRESET m_BomSettings;
std::vector<BOM_PRESET> m_BomPresets; std::vector<BOM_PRESET> m_BomPresets;
/// List of stored BOM format presets /// 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; BOM_FMT_PRESET m_BomFmtSettings;
std::vector<BOM_FMT_PRESET> m_BomFmtPresets; 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_export_pcb_svg.cpp
cli/command_fp_export_svg.cpp cli/command_fp_export_svg.cpp
cli/command_fp_upgrade.cpp cli/command_fp_upgrade.cpp
cli/command_export_sch_bom.cpp
cli/command_export_sch_pythonbom.cpp cli/command_export_sch_pythonbom.cpp
cli/command_export_sch_netlist.cpp cli/command_export_sch_netlist.cpp
cli/command_export_sch_plot.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_pos.h"
#include "cli/command_export_pcb_svg.h" #include "cli/command_export_pcb_svg.h"
#include "cli/command_export_pcb_step.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_pythonbom.h"
#include "cli/command_export_sch_netlist.h" #include "cli/command_export_sch_netlist.h"
#include "cli/command_export_sch_plot.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::PCB_COMMAND pcbCmd{};
static CLI::EXPORT_SCH_COMMAND exportSchCmd{}; static CLI::EXPORT_SCH_COMMAND exportSchCmd{};
static CLI::SCH_COMMAND schCmd{}; static CLI::SCH_COMMAND schCmd{};
static CLI::EXPORT_SCH_BOM_COMMAND exportSchBomCmd{};
static CLI::EXPORT_SCH_PYTHONBOM_COMMAND exportSchPythonBomCmd{}; static CLI::EXPORT_SCH_PYTHONBOM_COMMAND exportSchPythonBomCmd{};
static CLI::EXPORT_SCH_NETLIST_COMMAND exportSchNetlistCmd{}; static CLI::EXPORT_SCH_NETLIST_COMMAND exportSchNetlistCmd{};
static CLI::EXPORT_SCH_PLOT_COMMAND exportSchDxfCmd{ "dxf", PLOT_FORMAT::DXF }; static CLI::EXPORT_SCH_PLOT_COMMAND exportSchDxfCmd{ "dxf", PLOT_FORMAT::DXF };
@ -199,6 +201,7 @@ static std::vector<COMMAND_ENTRY> commandStack = {
&exportSchNetlistCmd, &exportSchNetlistCmd,
&exportSchPdfCmd, &exportSchPdfCmd,
&exportSchPostscriptCmd, &exportSchPostscriptCmd,
&exportSchBomCmd,
&exportSchPythonBomCmd, &exportSchPythonBomCmd,
&exportSchSvgCmd &exportSchSvgCmd
} }