48#include <wx/textdlg.h>
49#include <wx/filedlg.h>
65#define COLUMN_MARGIN 4
67#define COLUMN_MARGIN 15
115 int col =
m_grid->GetGridCursorCol();
120 menu.AppendSeparator();
125 menu.AppendSeparator();
132 int row =
m_grid->GetGridCursorRow();
133 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
135 if( refs.size() == 1 && refs[0].GetSymbol() )
137 menu.AppendSeparator();
142 auto variant = sym->
GetVariant( refs[0].GetSheetPath(), variantName );
144 if( variant && variant->m_SymbolOverride )
154 int row =
m_grid->GetGridCursorRow();
155 int col =
m_grid->GetGridCursorCol();
160 wxString fpid =
m_grid->GetCellValue( row, col );
164 if( frame->ShowModal( &fpid,
m_dlg ) )
165 m_grid->SetCellValue( row, col, fpid );
172 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
184 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
186 if( refs.size() != 1 || !refs[0].GetSymbol() )
191 std::vector<SCH_ITEM*> items = { refs[0].GetSymbol() };
192 selTool->
SyncSelection( refs[0].GetSheetPath(),
nullptr, items );
201 if( !
m_grid->CommitPendingChanges(
false ) )
209 m_dlg->ShowHideColumn( col, show );
211 wxString fieldName =
m_dataModel->GetColFieldName( col );
253 if(
resolver.ShowModal() != wxID_OK )
294 wxGridCellAttr* attr =
new wxGridCellAttr;
295 attr->SetReadOnly(
true );
298 attr =
new wxGridCellAttr;
299 attr->SetRenderer(
new wxGridCellBoolRenderer() );
301 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
304 attr =
new wxGridCellAttr;
305 attr->SetRenderer(
new wxGridCellBoolRenderer() );
307 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
313 m_filter->SetDescriptiveText(
_(
"Filter" ) );
315 attr =
new wxGridCellAttr;
319 m_grid->UseNativeColHeader(
true );
327 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
336 wxString variantToSelect;
339 variantToSelect =
m_job->GetSelectedVariant();
341 variantToSelect =
m_parent->Schematic().GetCurrentVariant();
343 if( !variantToSelect.IsEmpty() )
347 if( toSelect == wxNOT_FOUND )
360 SetTitle(
m_job->GetSettingsDialogTitle() );
362 SetTitle(
_(
"Symbol Fields Table" ) );
384 CallAfter( [
this, cfg]()
416 m_parent->Schematic().AddListener(
this );
421 m_grid->EnableEditing(
false );
439 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
441 if(
m_grid->IsColShown( i ) )
443 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
458 m_grid->PopEventHandler(
true );
466 wxGridCellAttr* attr =
new wxGridCellAttr;
467 attr->SetReadOnly(
false );
491 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
492 attr->SetRenderer(
new wxGridCellNumberRenderer() );
497 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
510 attr->SetEditor(
m_grid->GetDefaultEditor() );
519 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
522 m_grid->AutoSizeColumns(
false );
524 bool sortAscending =
true;
526 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
552 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
562 int maxWidth = defaultDlgSize.x / 3;
564 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
574 m_grid->SetSortingColumn( sortCol, sortAscending );
580 if( !wxDialog::TransferDataToWindow() )
603 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
606 field.
name = fieldName;
607 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
610 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
631 fmtPreset.
name =
m_job->m_bomFmtPresetName;
653 if( selection.GetSize() == 1 )
665 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
667 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
672 if( ref.GetSymbol() == symbol )
686 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
692 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
696 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
697 m_grid->GoToCell( row, valueCol );
698 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
699 m_grid->GoToCell( row, refCol );
700 else if( anyCol != -1 )
701 m_grid->GoToCell( row, anyCol );
719 if( !
m_grid->CommitPendingChanges() )
722 if( !wxDialog::TransferDataFromWindow() )
733 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
737 if( !commit.
Empty() )
739 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
744 m_parent->SetCurrentSheet( currentSheet );
753 bool show,
bool groupBy,
bool addedByUser )
766 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser );
768 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
769 m_grid->ProcessTableMessage( msg );
772 [&]() -> std::pair<int, int>
783 auto addMandatoryField =
784 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
805 std::set<wxString> userFieldNames;
813 if( !field.IsMandatory() && !field.IsPrivate() )
814 userFieldNames.insert( field.GetName() );
818 for(
const wxString& fieldName : userFieldNames )
824 if( userFieldNames.count( tfn.m_Name ) == 0 )
832 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
834 if( dlg.ShowModal() != wxID_OK )
837 wxString fieldName = dlg.GetValue();
839 if( fieldName.IsEmpty() )
845 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
849 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
872 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
878 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
884 int col =
m_dataModel->GetFieldNameCol( fieldName );
904 if( selectedRows.empty() )
907 int row = selectedRows[0];
913 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
923 int col =
m_dataModel->GetFieldNameCol( fieldName );
924 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
926 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
928 if( dlg.ShowModal() != wxID_OK )
931 wxString newFieldName = dlg.GetValue();
934 if( newFieldName == fieldName )
938 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
940 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
949 if( labelIsAutogenerated )
981 switch( aEvent.GetSelection() )
983 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
984 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
985 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
1007 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
1008 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
1009 "symbols are included on export." ),
1011 menu.Check( 4204, !
m_dataModel->GetExcludeDNP() );
1013 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
1014 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
1015 "are never included on export." ),
1017 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
1019 menu.AppendSeparator();
1021 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1022 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
1026 menu.Append( 4207,
_(
"Select on Cross-probe" ),
1027 _(
"Select corresponding item on canvas when it is selected in the table" ),
1032 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1034 if( menu_id == 0 || menu_id == 4204 )
1042 else if( menu_id == 1 || menu_id == 4205 )
1050 else if( menu_id == 3 || menu_id == 4206 )
1057 else if( menu_id == 4 || menu_id == 4207 )
1069 int sortCol = aEvent.GetCol();
1070 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1082 if(
m_grid->IsSortingBy( sortCol ) )
1085 ascending = !
m_grid->IsSortOrderAscending();
1103 int origPos = aEvent.GetCol();
1108 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1110 if(
m_grid->IsColShown( i ) )
1112 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1120 int newPos =
m_grid->GetColPos( origPos );
1123 if( newPos < origPos )
1164 int row = aEvent.GetRow();
1166 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1168 switch( aEvent.GetCol() )
1174 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1179 m_grid->SetColLabelValue( dataCol, label );
1197 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1209 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1211 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1213 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1220 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1222 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1257 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1259 m_grid->ClearSelection();
1262 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1275 wxPoint pos = aEvent.GetPosition();
1277 m_grid->CalcUnscrolledPosition( pos.x, pos.y, &ux, &uy );
1278 int row =
m_grid->YToRow( uy );
1279 int col =
m_grid->XToCol( ux );
1282 if( row == wxNOT_FOUND || col == wxNOT_FOUND )
1284 m_grid->GetGridWindow()->UnsetToolTip();
1288 wxString rawValue =
m_dataModel->GetValue( row, col );
1290 if( rawValue.Contains( wxT(
"${" ) ) )
1292 m_grid->GetGridWindow()->SetToolTip( rawValue );
1296 m_grid->GetGridWindow()->UnsetToolTip();
1311 std::set<SCH_REFERENCE> refs;
1312 std::set<SCH_ITEM*> symbols;
1315 if( aEvent.Selecting() )
1317 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1324 symbols.insert( ref.GetSymbol() );
1331 if( refs.size() > 0 )
1335 wxString symbol_path = refs.begin()->GetFullPath();
1348 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1350 if( refs.size() > 0 )
1351 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1385 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1392 if( saveIncludeExcudedFromBOM )
1425 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1428 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1433 if( saveDlg.ShowModal() == wxID_CANCEL )
1437 wxFileName file = wxFileName( saveDlg.GetPath() );
1438 wxString defaultPath = fn.GetPathWithSep();
1440 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1442 if( !file.MakeRelativeTo( defaultPath ) )
1444 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1445 "file volume)!" ) );
1479 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1480 _(
"OK" ),
_(
"Cancel" ) )
1490 std::function<bool( wxString* )> textResolver =
1491 [&]( wxString* token ) ->
bool
1496 return schematic.ResolveTextVar( &schematic.CurrentSheet(), token, 0 );
1501 if(
path.IsEmpty() )
1507 if(
path.IsEmpty() )
1509 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1519 wxFileName outputFile = wxFileName::FileName(
path );
1525 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1530 wxFFile out( outputFile.GetFullPath(),
"wb" );
1532 if( !out.IsOpened() )
1534 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1543 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1557 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1566 EndModal( wxID_CANCEL );
1588 m_job->m_bomFmtPresetName = wxEmptyString;
1593 m_job->m_bomPresetName = wxEmptyString;
1611 m_job->m_fieldsOrdered.clear();
1612 m_job->m_fieldsLabels.clear();
1613 m_job->m_fieldsGroupBy.clear();
1617 if( modelField.show )
1618 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1620 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1622 m_job->m_fieldsLabels.emplace_back( modelField.label );
1624 if( modelField.groupBy )
1625 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1630 EndModal( wxID_OK );
1653 m_grid->CommitPendingChanges(
true );
1669 m_parent->Schematic().RemoveListener(
this );
1672 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1674 if( wxWindow* parent = GetParent() )
1675 wxQueueEvent( parent, evt );
1681 std::vector<BOM_PRESET> ret;
1683 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1685 if( !pair.second.readOnly )
1686 ret.emplace_back( pair.second );
1698 for(
const BOM_PRESET& preset : aPresetList )
1716 wxCommandEvent
dummy;
1759 int default_idx = 0;
1763 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1788 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1790 const BOM_PRESET& preset = aPair.second;
1793 if( !( preset.sortAsc == current.sortAsc
1794 && preset.filterString == current.filterString
1795 && preset.groupSymbols == current.groupSymbols
1796 && preset.excludeDNP == current.excludeDNP
1797 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1808 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1812 std::vector<BOM_FIELD>
A,
B;
1814 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1816 if( field.show || field.groupBy )
1817 A.emplace_back( field );
1822 if( field.show || field.groupBy )
1823 B.emplace_back( field );
1829 if( it != m_bomPresets.end() )
1833 bool do_translate = it->second.readOnly;
1834 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1835 m_cbBomPresets->SetStringSelection(
text );
1839 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1842 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1851 wxString ui_label = aName;
1855 if( presetName == aName )
1857 if( preset.readOnly ==
true )
1858 ui_label = wxGetTranslation( aName );
1883 auto resetSelection =
1892 if(
index == count - 3 )
1898 else if(
index == count - 2 )
1906 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1908 if( dlg.ShowModal() != wxID_OK )
1914 name = dlg.GetValue();
1932 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1933 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1940 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1961 else if(
index == count - 1 )
1964 wxArrayString headers;
1965 std::vector<wxArrayString> items;
1967 headers.Add(
_(
"Presets" ) );
1971 if( !preset.readOnly )
1975 items.emplace_back( item );
1987 if( idx != wxNOT_FOUND )
2038 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
2040 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2061 int col =
m_dataModel->GetFieldNameCol( fieldName );
2065 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2070 std::string fieldNameStr( fieldName.ToUTF8() );
2073 const wxString& label =
m_dataModel->GetColLabelValue( col );
2075 m_grid->SetColLabelValue( col, label );
2090 bool groupBy =
m_dataModel->GetGroupColumn( col );
2114 std::vector<BOM_FMT_PRESET> ret;
2118 if( !preset.readOnly )
2119 ret.emplace_back( preset );
2149 wxCommandEvent
dummy;
2191 int default_idx = 0;
2220 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2222 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2223 && aPair.second.stringDelimiter == current.stringDelimiter
2224 && aPair.second.refDelimiter == current.refDelimiter
2225 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2226 && aPair.second.keepTabs == current.keepTabs
2227 && aPair.second.keepLineBreaks == current.keepLineBreaks
2228 && aPair.second.includeByteOrderMark == current.includeByteOrderMark );
2235 bool do_translate = it->second.readOnly;
2236 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2255 wxString ui_label = aName;
2259 if( presetName == aName )
2261 if( preset.readOnly )
2262 ui_label = wxGetTranslation( aName );
2287 auto resetSelection =
2296 if(
index == count - 3 )
2302 else if(
index == count - 2 )
2310 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2312 if( dlg.ShowModal() != wxID_OK )
2318 name = dlg.GetValue();
2336 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2337 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2344 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2365 else if(
index == count - 1 )
2368 wxArrayString headers;
2369 std::vector<wxArrayString> items;
2371 headers.Add(
_(
"Presets" ) );
2373 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2375 if( !pair.second.readOnly )
2378 item.Add( pair.first );
2379 items.emplace_back( item );
2391 if( idx != wxNOT_FOUND )
2447 bool modified =
false;
2450 std::vector<BOM_PRESET> presets;
2454 if( !preset.readOnly )
2455 presets.emplace_back( preset );
2471 std::vector<BOM_FMT_PRESET> fmts;
2475 if( !preset.readOnly )
2476 fmts.emplace_back( preset );
2515 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2521 std::set<SCH_SYMBOL*> symbols;
2525 symbols.insert( ref.GetSymbol() );
2530 for(
SCH_FIELD& field : symbol->GetFields() )
2531 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2583 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2589 std::set<SCH_SYMBOL*> symbols;
2593 symbols.insert( ref.GetSymbol() );
2598 for(
SCH_FIELD& field : symbol->GetFields() )
2599 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2617 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2631 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2639 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2647 std::set<wxString> selectedFullPaths;
2649 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2650 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2652 for(
size_t i = 0; i < topLeft.size(); ++i )
2654 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2657 selectedFullPaths.insert( ref.GetFullPath() );
2661 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2663 for(
int row : selectedRows )
2666 selectedFullPaths.insert( ref.GetFullPath() );
2669 int cursorRow =
m_grid->GetGridCursorRow();
2671 if( cursorRow >= 0 && selectedFullPaths.empty() )
2674 selectedFullPaths.insert( ref.GetFullPath() );
2677 return selectedFullPaths;
2683 if( aFullPaths.empty() )
2686 m_grid->ClearSelection();
2688 bool firstSelection =
true;
2690 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2692 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2696 if( aFullPaths.count( ref.GetFullPath() ) )
2698 m_grid->SelectRow( row,
true );
2700 if( firstSelection )
2702 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2703 firstSelection =
false;
2718 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2745 if( basePath.Path() == instance.m_Path )
2753 subSheets.push_back( sheetPath );
2771 if( !
m_parent->ShowAddVariantDialog(
this ) )
2774 wxArrayString ctrlContents;
2777 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2778 ctrlContents.Add( variant );
2783 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2787 if( newSelection != wxNOT_FOUND )
2799 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2801 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2802 10000, wxICON_ERROR );
2811 m_parent->Schematic().DeleteVariant( variantName, &commit );
2813 if( !commit.
Empty() )
2814 commit.
Push( wxString::Format( wxS(
"Delete Variant '%s'" ), variantName ) );
2818 int newSelection = std::max( 0, selection - 1 );
2822 m_parent->SetCurrentVariant( selectedVariant );
2824 if(
m_grid->CommitPendingChanges(
true ) )
2826 m_dataModel->SetCurrentVariant( selectedVariant );
2837 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2846 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2848 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2849 10000, wxICON_ERROR );
2855 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2856 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2858 if( dlg.ShowModal() == wxID_CANCEL )
2861 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2864 if( newVariantName.IsEmpty() )
2866 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2873 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2875 10000, wxICON_ERROR );
2880 if( newVariantName == oldVariantName )
2884 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2886 if( existingName.CmpNoCase( newVariantName ) == 0
2887 && existingName.CmpNoCase( oldVariantName ) != 0 )
2889 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2891 0000, wxICON_ERROR );
2896 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2900 ctrlContents.Remove( oldVariantName );
2901 ctrlContents.Add( newVariantName );
2907 if( newSelection != wxNOT_FOUND )
2911 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2920 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2922 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2923 10000, wxICON_ERROR );
2929 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2930 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2932 if( dlg.ShowModal() == wxID_CANCEL )
2935 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2938 if( newVariantName.IsEmpty() )
2940 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2947 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2949 10000, wxICON_ERROR );
2953 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2957 ctrlContents.Add( newVariantName );
2963 if( newSelection != wxNOT_FOUND )
2967 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2975 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2977 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot edit the default variant description." ), 10000,
2983 wxString currentDesc =
m_parent->Schematic().GetVariantDescription( variantName );
2985 wxDialog dlg(
this, wxID_ANY, wxString::Format(
_(
"Edit Description for '%s'" ), variantName ), wxDefaultPosition,
2986 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
2988 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
2990 wxStaticText* label =
new wxStaticText( &dlg, wxID_ANY,
_(
"Description:" ) );
2991 mainSizer->Add( label, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 10 );
2993 mainSizer->AddSpacer( 3 );
2995 wxTextCtrl* descCtrl =
2996 new wxTextCtrl( &dlg, wxID_ANY, currentDesc, wxDefaultPosition, wxSize( 300, 60 ), wxTE_MULTILINE );
2997 mainSizer->Add( descCtrl, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 10 );
2999 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
3000 btnSizer->AddButton(
new wxButton( &dlg, wxID_OK ) );
3001 btnSizer->AddButton(
new wxButton( &dlg, wxID_CANCEL ) );
3002 btnSizer->Realize();
3003 mainSizer->Add( btnSizer, 0, wxALL | wxALIGN_RIGHT, 5 );
3005 dlg.SetSizer( mainSizer );
3009 if( dlg.ShowModal() == wxID_CANCEL )
3012 wxString newDesc = descCtrl->GetValue().Trim().Trim(
false );
3014 m_parent->Schematic().SetVariantDescription( variantName, newDesc );
3021 wxString currentVariant;
3028 m_grid->CommitPendingChanges(
true );
3031 m_parent->SetCurrentVariant( selectedVariant );
3033 m_dataModel->SetCurrentVariant( selectedVariant );
3048 currentVariant =
m_parent->Schematic().GetCurrentVariant();
3050 if( currentVariant != selectedVariant )
3051 m_parent->SetCurrentVariant( selectedVariant );
3054 if( currentVariant != selectedVariant )
3056 m_grid->CommitPendingChanges(
true );
3062 if( !commit.
Empty() )
3064 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
3069 m_dataModel->SetCurrentVariant( selectedVariant );
3088 bool canModify = ( selection != wxNOT_FOUND ) && ( selection != 0 );
3116 return m_parent->Schematic().GetCurrentVariant();
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
STD_BITMAP_BUTTON * m_addVariantButton
wxTextCtrl * m_textStringDelimiter
STD_BITMAP_BUTTON * m_renameVariantButton
wxTextCtrl * m_textRefDelimiter
wxTextCtrl * m_outputFileName
wxChoice * m_cbBomFmtPresets
wxCheckBox * m_checkIncludeByteOrderMark
STD_BITMAP_BUTTON * m_removeFieldButton
wxTextCtrl * m_textOutput
STD_BITMAP_BUTTON * m_renameFieldButton
wxTextCtrl * m_textFieldDelimiter
wxButton * m_buttonExport
wxSplitterWindow * m_splitterMainWindow
wxCheckBox * m_checkKeepTabs
STD_BITMAP_BUTTON * m_copyVariantButton
wxCheckBox * m_checkKeepLineBreaks
STD_BITMAP_BUTTON * m_bMenu
STD_BITMAP_BUTTON * m_deleteVariantButton
STD_BITMAP_BUTTON * m_sidebarButton
STD_BITMAP_BUTTON * m_browseButton
STD_BITMAP_BUTTON * m_addFieldButton
STD_BITMAP_BUTTON * m_editVariantDescButton
WX_GRID * m_viewControlsGrid
wxListBox * m_variantListBox
STD_BITMAP_BUTTON * m_bRefreshPreview
wxChoice * m_cbBomPresets
wxTextCtrl * m_textRefRangeDelimiter
STD_BITMAP_BUTTON * m_bRefresh
wxCheckBox * m_groupSymbolsBox
wxSplitterWindow * m_splitter_left
static wxString GetDefaultBomFileName(const wxString &aInputFileName)
Derive the default BOM output file name from the input file name by swapping the extension to CSV.
void setSideBarButtonLook(bool aIsLeftPanelCollapsed)
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
void ExcludeFromControlUndoRedo(wxWindow *aWindow)
Opt a control out of the dialog's generic Ctrl+Z/Ctrl+Y undo/redo.
void OptOut(wxWindow *aWindow)
Opt out of control state saving.
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int horizPixelsFromDU(int x) const
Convert an integer number of dialog units to pixels, horizontally.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxString resolveVariant() const
void OnSaveAndContinue(wxCommandEvent &aEvent) override
void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem) override
BOM_FMT_PRESET * m_currentBomFmtPreset
void onAddVariant(wxCommandEvent &aEvent) override
void OnPreviewRefresh(wxCommandEvent &event) override
DIALOG_SYMBOL_FIELDS_TABLE(SCH_EDIT_FRAME *parent, JOB_EXPORT_BOM *aJob=nullptr)
void OnAddField(wxCommandEvent &event) override
SCH_REFERENCE_LIST getSheetSymbolReferences(SCH_SHEET &aSheet)
void SetUserBomPresets(std::vector< BOM_PRESET > &aPresetList)
void OnSidebarToggle(wxCommandEvent &event) override
void OnOk(wxCommandEvent &aEvent) override
void OnGroupSymbolsToggled(wxCommandEvent &event) override
~DIALOG_SYMBOL_FIELDS_TABLE() override
void OnColMove(wxGridEvent &aEvent)
void OnSchItemsAdded(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem) override
void loadDefaultBomFmtPresets()
std::map< wxString, BOM_PRESET > m_bomPresets
void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem) override
void ApplyBomFmtPreset(const wxString &aPresetName)
void ShowHideColumn(int aCol, bool aShow)
VIEW_CONTROLS_GRID_DATA_MODEL * m_viewControlsDataModel
SCH_EDIT_FRAME * m_parent
bool TransferDataFromWindow() override
SCH_REFERENCE_LIST m_symbolsList
void SetupColumnProperties(int aCol)
FIELDS_EDITOR_GRID_DATA_MODEL * m_dataModel
void updateBomPresetSelection(const wxString &aName)
void updateBomFmtPresetSelection(const wxString &aName)
void OnFilterText(wxCommandEvent &aEvent) override
std::map< FIELD_T, int > m_mandatoryFieldListIndexes
void OnRemoveField(wxCommandEvent &event) override
void OnTableCellClick(wxGridEvent &event) override
wxArrayString m_bomPresetMRU
void onVariantSelectionChange(wxCommandEvent &aEvent) override
void doApplyBomFmtPreset(const BOM_FMT_PRESET &aPreset)
void loadDefaultBomPresets()
void RestoreGridSelection(const std::set< wxString > &aFullPaths)
Restores the grid selection from a previously saved set of symbol full paths.
void OnScope(wxCommandEvent &event) override
void onBomPresetChanged(wxCommandEvent &aEvent)
void OnExport(wxCommandEvent &aEvent) override
void OnClose(wxCloseEvent &aEvent) override
void OnSchSheetChanged(SCHEMATIC &aSch) override
void syncBomFmtPresetSelection()
void DisableSelectionEvents()
void onCopyVariant(wxCommandEvent &aEvent) override
void onDeleteVariant(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
void OnTableRangeSelected(wxGridRangeSelectEvent &aEvent)
void OnMenu(wxCommandEvent &event) override
void updateVariantButtonStates()
void EnableSelectionEvents()
void setScope(FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE aScope)
std::vector< BOM_FMT_PRESET > GetUserBomFmtPresets() const
wxArrayString m_bomFmtPresetMRU
void OnCancel(wxCommandEvent &aEvent) override
std::map< wxString, BOM_FMT_PRESET > m_bomFmtPresets
BOM_FMT_PRESET GetCurrentBomFmtSettings()
Returns a formatting configuration corresponding to the values in the UI controls of the dialog.
std::set< wxString > SaveGridSelection()
Saves the current grid selection as a set of symbol full paths for later restoration.
void savePresetsToSchematic()
void SetupAllColumnProperties()
void AddField(const wxString &displayName, const wxString &aCanonicalName, bool show, bool groupBy, bool addedByUser=false)
SCH_REFERENCE_LIST getSymbolReferences(SCH_SYMBOL *aSymbol, SCH_REFERENCE_LIST &aCachedRefs)
wxString getSelectedVariant() const
void OnGridMouseMove(wxMouseEvent &aEvent)
SCHEMATIC_SETTINGS & m_schSettings
void syncBomPresetSelection()
void doApplyBomPreset(const BOM_PRESET &aPreset)
void OnPageChanged(wxNotebookEvent &event) override
void SetUserBomFmtPresets(std::vector< BOM_FMT_PRESET > &aPresetList)
void OnRegroupSymbols(wxCommandEvent &aEvent) override
void OnViewControlsCellChanged(wxGridEvent &aEvent) override
void onRenameVariant(wxCommandEvent &aEvent) override
void OnColSort(wxGridEvent &aEvent)
std::vector< BOM_PRESET > GetUserBomPresets() const
void OnOutputFileBrowseClicked(wxCommandEvent &event) override
void LoadFieldNames()
Construct the rows of m_fieldsCtrl and the columns of m_dataModel from a union of all field names in ...
void onBomFmtPresetChanged(wxCommandEvent &aEvent)
void ApplyBomPreset(const wxString &aPresetName)
void rebuildBomFmtPresetsWidget()
BOM_PRESET * m_lastSelectedBomPreset
void rebuildBomPresetsWidget()
BOM_PRESET * m_currentBomPreset
void onEditVariantDescription(wxCommandEvent &aEvent) override
BOM_FMT_PRESET * m_lastSelectedBomFmtPreset
void OnRenameField(wxCommandEvent &event) override
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
PANEL_SYMBOL_FIELDS_TABLE m_FieldEditorPanel
static const wxString ITEM_NUMBER_VARIABLE
static const wxString QUANTITY_VARIABLE
VIEW_CONTROLS_GRID_DATA_MODEL * m_viewControlsDataModel
DIALOG_SYMBOL_FIELDS_TABLE * m_dlg
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
FIELDS_EDITOR_GRID_TRICKS(DIALOG_SYMBOL_FIELDS_TABLE *aParent, WX_GRID *aGrid, VIEW_CONTROLS_GRID_DATA_MODEL *aViewFieldsData, FIELDS_EDITOR_GRID_DATA_MODEL *aDataModel, EMBEDDED_FILES *aFiles)
FIELDS_EDITOR_GRID_DATA_MODEL * m_dataModel
A general-purpose text renderer for WX_GRIDs backed by WX_GRID_TABLE_BASE tables that can handle draw...
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
GRID_TRICKS(WX_GRID *aGrid)
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
static REPORTER & GetInstance()
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Holds all the data relating to one schematic.
wxString GetCurrentVariant() const
Return the current variant being edited.
wxArrayString GetVariantNamesForUI() const
Return an array of variant names for using in wxWidgets UI controls.
SCH_SHEET_PATH & CurrentSheet() const
static TOOL_ACTION clearVariantSymbol
static TOOL_ACTION setVariantSymbol
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Handle actions specific to the schematic editor.
Schematic editor (Eeschema) main window.
SCHEMATIC & Schematic() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void AddItem(const SCH_REFERENCE &aItem)
A helper to define a symbol's reference designator in a schematic.
void Split()
Attempt to split the reference designator into a name (U) and number (1).
SCH_SYMBOL * GetSymbol() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetSymbolsWithinPath(SCH_REFERENCE_LIST &aReferences, const SCH_SHEET_PATH &aSheetPath, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets that are contained wi...
void GetSheetsWithinPath(std::vector< SCH_SHEET_PATH > &aSheets, const SCH_SHEET_PATH &aSheetPath) const
Add a SCH_SHEET_PATH object to aSheets for each sheet in the list that are contained within aSheetPat...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
std::optional< SCH_SYMBOL_VARIANT > GetVariant(const SCH_SHEET_PATH &aInstance, const wxString &aVariantName) const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
bool IsPower() const override
VIEW_CONTROLS_GRID_TRICKS(WX_GRID *aGrid)
void doPopupSelection(wxCommandEvent &event) override
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
wxString NormalizeFilePathForTextVars(const wxString &aPath)
Normalize a file path so its text variables survive ExpandTextVars.
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn't yet exist.
bool IsGeneratedField(const wxString &aSource)
Returns true if the string is generated, e.g contains a single text var reference.
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
wxDEFINE_EVENT(EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxCommandEvent)
FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE SCOPE
@ MYID_SET_VARIANT_SYMBOL
@ MYID_CLEAR_VARIANT_SYMBOL
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
This file is part of the common library.
static FILENAME_RESOLVER * resolver
std::vector< FIELD_CASE_CONFLICT > DetectFieldCaseConflicts(const SCH_REFERENCE_LIST &aSymbols)
#define DISPLAY_NAME_COLUMN
#define SHOW_FIELD_COLUMN
@ FRAME_FOOTPRINT_CHOOSER
@ GRIDTRICKS_FIRST_SHOWHIDE
@ GRIDTRICKS_FIRST_CLIENT_ID
static const std::string CsvFileExtension
static wxString CsvFileWildcard()
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ SYMBOL_FILTER_NON_POWER
std::vector< FAB_LAYER_COLOR > dummy
wxString GetDefaultVariantName()
int SortVariantNames(const wxString &aLhs, const wxString &aRhs)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
bool includeByteOrderMark
static BOM_FMT_PRESET CSV()
static std::vector< BOM_FMT_PRESET > BuiltInPresets()
wxString refRangeDelimiter
static BOM_PRESET DefaultEditing()
std::vector< BOM_FIELD > fieldsOrdered
static std::vector< BOM_PRESET > BuiltInPresets()
std::map< std::string, int > field_widths
A simple container for sheet instance information.
Hold a name of a symbol's field, field value, and default visibility.
bool FieldNamesAreDuplicates(const wxString &aLhs, const wxString &aRhs, std::initializer_list< FIELD_T > aMandatoryFields)
Test whether two field names should be treated as duplicates for the purposes of field name uniquenes...
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
Definition of file extensions used in Kicad.