51#include <wx/textdlg.h>
52#include <wx/filedlg.h>
64#define COLUMN_MARGIN 4
66#define COLUMN_MARGIN 15
112 int col =
m_grid->GetGridCursorCol();
117 menu.AppendSeparator();
122 menu.AppendSeparator();
130 int row =
m_grid->GetGridCursorRow();
131 int col =
m_grid->GetGridCursorCol();
136 wxString fpid =
m_grid->GetCellValue( row, col );
140 if( frame->ShowModal( &fpid,
m_dlg ) )
141 m_grid->SetCellValue( row, col, fpid );
148 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
154 if( !
m_grid->CommitPendingChanges(
false ) )
162 m_dlg->ShowHideColumn( col, show );
164 wxString fieldName =
m_dataModel->GetColFieldName( col );
229 wxGridCellAttr* attr =
new wxGridCellAttr;
230 attr->SetReadOnly(
true );
233 attr =
new wxGridCellAttr;
234 attr->SetRenderer(
new wxGridCellBoolRenderer() );
236 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
239 attr =
new wxGridCellAttr;
240 attr->SetRenderer(
new wxGridCellBoolRenderer() );
242 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
248 m_filter->SetDescriptiveText(
_(
"Filter" ) );
250 attr =
new wxGridCellAttr;
254 m_grid->UseNativeColHeader(
true );
258 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
266 if( !
m_parent->Schematic().GetCurrentVariant().IsEmpty() )
270 if( toSelect == wxNOT_FOUND )
283 SetTitle(
m_job->GetSettingsDialogTitle() );
305 CallAfter( [
this, cfg]()
334 m_parent->Schematic().AddListener(
this );
339 m_grid->EnableEditing(
false );
358 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
360 if(
m_grid->IsColShown( i ) )
362 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
376 m_grid->PopEventHandler(
true );
386 if( aIsLeftPanelCollapsed )
401 wxGridCellAttr* attr =
new wxGridCellAttr;
402 attr->SetReadOnly(
false );
426 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
427 attr->SetRenderer(
new wxGridCellNumberRenderer() );
432 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
445 attr->SetEditor(
m_grid->GetDefaultEditor() );
454 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
457 m_grid->AutoSizeColumns(
false );
459 bool sortAscending =
true;
461 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
487 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
497 int maxWidth = defaultDlgSize.x / 3;
499 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
509 m_grid->SetSortingColumn( sortCol, sortAscending );
515 if( !wxDialog::TransferDataToWindow() )
538 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
541 field.
name = fieldName;
542 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
545 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
566 fmtPreset.
name =
m_job->m_bomFmtPresetName;
585 wxCommandEvent
dummy;
588 if( selection.GetSize() == 1 )
600 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
602 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
607 if( ref.GetSymbol() == symbol )
621 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
627 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
631 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
632 m_grid->GoToCell( row, valueCol );
633 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
634 m_grid->GoToCell( row, refCol );
635 else if( anyCol != -1 )
636 m_grid->GoToCell( row, anyCol );
654 if( !
m_grid->CommitPendingChanges() )
657 if( !wxDialog::TransferDataFromWindow() )
668 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
672 if( !commit.
Empty() )
674 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
679 m_parent->SetCurrentSheet( currentSheet );
688 bool show,
bool groupBy,
bool addedByUser )
698 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
700 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
701 m_grid->ProcessTableMessage( msg );
704 [&]() -> std::pair<int, int>
715 auto addMandatoryField =
716 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
736 std::set<wxString> userFieldNames;
744 if( !field.IsMandatory() && !field.IsPrivate() )
745 userFieldNames.insert( field.GetName() );
749 for(
const wxString& fieldName : userFieldNames )
755 if( userFieldNames.count( tfn.m_Name ) == 0 )
763 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
765 if( dlg.ShowModal() != wxID_OK )
768 wxString fieldName = dlg.GetValue();
770 if( fieldName.IsEmpty() )
776 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
778 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
780 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
803 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
809 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
815 int col =
m_dataModel->GetFieldNameCol( fieldName );
835 if( selectedRows.empty() )
838 int row = selectedRows[0];
844 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
854 int col =
m_dataModel->GetFieldNameCol( fieldName );
855 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
857 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
859 if( dlg.ShowModal() != wxID_OK )
862 wxString newFieldName = dlg.GetValue();
865 if( newFieldName == fieldName )
869 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
871 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
880 if( labelIsAutogenerated )
904#if defined( __WXOSX__ )
905 wxPoint pos = aEvent.GetPosition();
906 wxRect ctrlRect =
m_filter->GetScreenRect();
907 int buttonWidth = ctrlRect.GetHeight();
910 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
911 SetCursor( wxCURSOR_ARROW );
912 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
913 SetCursor( wxCURSOR_ARROW );
915 SetCursor( wxCURSOR_IBEAM );
930 switch( aEvent.GetSelection() )
932 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
933 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
934 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
956 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
957 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
958 "symbols are included on export." ),
962 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
963 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
964 "are never included on export." ),
966 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
968 menu.AppendSeparator();
970 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
971 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
975 menu.Append( 4207,
_(
"Select on Cross-probe" ),
976 _(
"Select corresponding item on canvas when it is selected in the table" ),
981 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
983 if( menu_id == 0 || menu_id == 4204 )
991 else if( menu_id == 1 || menu_id == 4205 )
999 else if( menu_id == 3 || menu_id == 4206 )
1006 else if( menu_id == 4 || menu_id == 4207 )
1018 int sortCol = aEvent.GetCol();
1019 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1031 if(
m_grid->IsSortingBy( sortCol ) )
1034 ascending = !
m_grid->IsSortOrderAscending();
1052 int origPos = aEvent.GetCol();
1057 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1059 if(
m_grid->IsColShown( i ) )
1061 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1069 int newPos =
m_grid->GetColPos( origPos );
1072 if( newPos < origPos )
1113 int row = aEvent.GetRow();
1115 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1117 switch( aEvent.GetCol() )
1123 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1128 m_grid->SetColLabelValue( dataCol, label );
1146 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1158 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1160 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1162 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1169 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1171 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1220 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1222 m_grid->ClearSelection();
1225 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1244 std::set<SCH_REFERENCE> refs;
1245 std::set<SCH_ITEM*> symbols;
1248 if( aEvent.Selecting() )
1250 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1257 symbols.insert( ref.GetSymbol() );
1264 if( refs.size() > 0 )
1268 wxString symbol_path = refs.begin()->GetFullPath();
1281 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1283 if( refs.size() > 0 )
1284 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1297 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1346 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1353 if( saveIncludeExcudedFromBOM )
1397 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1400 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1405 if( saveDlg.ShowModal() == wxID_CANCEL )
1409 wxFileName file = wxFileName( saveDlg.GetPath() );
1410 wxString defaultPath = fn.GetPathWithSep();
1412 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1414 if( !file.MakeRelativeTo( defaultPath ) )
1416 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1417 "file volume)!" ) );
1451 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1452 _(
"OK" ),
_(
"Cancel" ) )
1462 std::function<bool( wxString* )> textResolver =
1463 [&]( wxString* token ) ->
bool
1473 if(
path.IsEmpty() )
1475 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1482 wxFileName outputFile = wxFileName::FileName(
path );
1488 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1493 wxFFile out( outputFile.GetFullPath(),
"wb" );
1495 if( !out.IsOpened() )
1497 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1506 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1513 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1521 EndModal( wxID_CANCEL );
1538 m_job->m_bomFmtPresetName = wxEmptyString;
1543 m_job->m_bomPresetName = wxEmptyString;
1560 m_job->m_fieldsOrdered.clear();
1561 m_job->m_fieldsLabels.clear();
1562 m_job->m_fieldsGroupBy.clear();
1566 if( modelField.show )
1567 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1569 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1571 m_job->m_fieldsLabels.emplace_back( modelField.label );
1573 if( modelField.groupBy )
1574 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1579 if( !selectedVariant.IsEmpty() )
1580 m_job->m_variantNames.push_back( selectedVariant );
1582 EndModal( wxID_OK );
1599 m_grid->CommitPendingChanges(
true );
1615 m_parent->Schematic().RemoveListener(
this );
1618 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1620 if( wxWindow* parent = GetParent() )
1621 wxQueueEvent( parent, evt );
1627 std::vector<BOM_PRESET> ret;
1629 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1631 if( !pair.second.readOnly )
1632 ret.emplace_back( pair.second );
1644 for(
const BOM_PRESET& preset : aPresetList )
1662 wxCommandEvent
dummy;
1705 int default_idx = 0;
1709 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1734 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1736 const BOM_PRESET& preset = aPair.second;
1739 if( !( preset.sortAsc == current.sortAsc
1740 && preset.filterString == current.filterString
1741 && preset.groupSymbols == current.groupSymbols
1742 && preset.excludeDNP == current.excludeDNP
1743 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1754 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1758 std::vector<BOM_FIELD>
A,
B;
1760 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1762 if( field.show || field.groupBy )
1763 A.emplace_back( field );
1768 if( field.show || field.groupBy )
1769 B.emplace_back( field );
1775 if( it != m_bomPresets.end() )
1779 bool do_translate = it->second.readOnly;
1780 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1781 m_cbBomPresets->SetStringSelection(
text );
1785 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1788 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1797 wxString ui_label = aName;
1801 if( presetName == aName )
1803 if( preset.readOnly ==
true )
1804 ui_label = wxGetTranslation( aName );
1829 auto resetSelection =
1838 if(
index == count - 3 )
1844 else if(
index == count - 2 )
1852 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1854 if( dlg.ShowModal() != wxID_OK )
1860 name = dlg.GetValue();
1878 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1879 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1886 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1907 else if(
index == count - 1 )
1910 wxArrayString headers;
1911 std::vector<wxArrayString> items;
1913 headers.Add(
_(
"Presets" ) );
1917 if( !preset.readOnly )
1921 items.emplace_back( item );
1933 if( idx != wxNOT_FOUND )
1983 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
1985 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2006 int col =
m_dataModel->GetFieldNameCol( fieldName );
2010 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2015 std::string fieldNameStr( fieldName.ToUTF8() );
2018 const wxString& label =
m_dataModel->GetColLabelValue( col );
2020 m_grid->SetColLabelValue( col, label );
2035 bool groupBy =
m_dataModel->GetGroupColumn( col );
2059 std::vector<BOM_FMT_PRESET> ret;
2063 if( !preset.readOnly )
2064 ret.emplace_back( preset );
2094 wxCommandEvent
dummy;
2136 int default_idx = 0;
2165 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2167 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2168 && aPair.second.stringDelimiter == current.stringDelimiter
2169 && aPair.second.refDelimiter == current.refDelimiter
2170 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2171 && aPair.second.keepTabs == current.keepTabs
2172 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2179 bool do_translate = it->second.readOnly;
2180 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2199 wxString ui_label = aName;
2203 if( presetName == aName )
2205 if( preset.readOnly )
2206 ui_label = wxGetTranslation( aName );
2231 auto resetSelection =
2240 if(
index == count - 3 )
2246 else if(
index == count - 2 )
2254 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2256 if( dlg.ShowModal() != wxID_OK )
2262 name = dlg.GetValue();
2280 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2281 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2288 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2309 else if(
index == count - 1 )
2312 wxArrayString headers;
2313 std::vector<wxArrayString> items;
2315 headers.Add(
_(
"Presets" ) );
2317 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2319 if( !pair.second.readOnly )
2322 item.Add( pair.first );
2323 items.emplace_back( item );
2335 if( idx != wxNOT_FOUND )
2390 bool modified =
false;
2393 std::vector<BOM_PRESET> presets;
2397 if( !preset.readOnly )
2398 presets.emplace_back( preset );
2414 std::vector<BOM_FMT_PRESET> fmts;
2418 if( !preset.readOnly )
2419 fmts.emplace_back( preset );
2444 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2458 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2464 std::set<SCH_SYMBOL*> symbols;
2468 symbols.insert( ref.GetSymbol() );
2473 for(
SCH_FIELD& field : symbol->GetFields() )
2474 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2512 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2526 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2529 m_parent->Schematic().GetCurrentVariant() );
2533 std::set<SCH_SYMBOL*> symbols;
2537 symbols.insert( ref.GetSymbol() );
2542 for(
SCH_FIELD& field : symbol->GetFields() )
2543 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2561 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2575 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2583 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2591 std::set<wxString> selectedFullPaths;
2593 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2594 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2596 for(
size_t i = 0; i < topLeft.size(); ++i )
2598 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2601 selectedFullPaths.insert( ref.GetFullPath() );
2605 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2607 for(
int row : selectedRows )
2610 selectedFullPaths.insert( ref.GetFullPath() );
2613 int cursorRow =
m_grid->GetGridCursorRow();
2615 if( cursorRow >= 0 && selectedFullPaths.empty() )
2618 selectedFullPaths.insert( ref.GetFullPath() );
2621 return selectedFullPaths;
2627 if( aFullPaths.empty() )
2630 m_grid->ClearSelection();
2632 bool firstSelection =
true;
2634 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2636 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2640 if( aFullPaths.count( ref.GetFullPath() ) )
2642 m_grid->SelectRow( row,
true );
2644 if( firstSelection )
2646 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2647 firstSelection =
false;
2662 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2689 if( basePath.Path() == instance.m_Path )
2697 subSheets.push_back( sheetPath );
2715 if( !
m_parent->ShowAddVariantDialog() )
2718 wxArrayString ctrlContents;
2721 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2722 ctrlContents.Add( variant );
2727 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2731 if( newSelection != wxNOT_FOUND )
2743 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2745 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2746 10000, wxICON_ERROR );
2752 m_parent->Schematic().DeleteVariant( variantName );
2754 int newSelection = std::max( 0, selection - 1 );
2758 m_parent->SetCurrentVariant( selectedVariant );
2760 if(
m_grid->CommitPendingChanges(
true ) )
2762 m_dataModel->SetCurrentVariant( selectedVariant );
2773 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2782 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2784 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2785 10000, wxICON_ERROR );
2791 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2792 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2794 if( dlg.ShowModal() == wxID_CANCEL )
2797 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2800 if( newVariantName.IsEmpty() )
2802 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2809 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2811 10000, wxICON_ERROR );
2816 if( newVariantName == oldVariantName )
2820 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2822 if( existingName.CmpNoCase( newVariantName ) == 0
2823 && existingName.CmpNoCase( oldVariantName ) != 0 )
2825 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2827 0000, wxICON_ERROR );
2832 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2835 ctrlContents.Remove( oldVariantName );
2836 ctrlContents.Add( newVariantName );
2842 if( newSelection != wxNOT_FOUND )
2846 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2855 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2857 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2858 10000, wxICON_ERROR );
2864 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2865 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2867 if( dlg.ShowModal() == wxID_CANCEL )
2870 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2873 if( newVariantName.IsEmpty() )
2875 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2882 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2884 10000, wxICON_ERROR );
2888 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2891 ctrlContents.Add( newVariantName );
2897 if( newSelection != wxNOT_FOUND )
2901 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2907 wxString currentVariant;
2914 currentVariant =
m_parent->Schematic().GetCurrentVariant();
2916 if( currentVariant != selectedVariant )
2917 m_parent->SetCurrentVariant( selectedVariant );
2920 if( currentVariant != selectedVariant )
2922 m_grid->CommitPendingChanges(
true );
2928 if( !commit.
Empty() )
2930 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
2935 m_dataModel->SetCurrentVariant( selectedVariant );
2954 bool canModify = ( selection != wxNOT_FOUND ) && ( selection != 0 );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
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...
wxCheckBox * m_checkKeepLineBreaks
STD_BITMAP_BUTTON * m_deleteVariantButton
STD_BITMAP_BUTTON * m_bRefreshPreview
STD_BITMAP_BUTTON * m_bMenu
STD_BITMAP_BUTTON * m_addVariantButton
DIALOG_SYMBOL_FIELDS_TABLE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Symbol Fields Table"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER)
wxCheckBox * m_checkKeepTabs
wxButton * m_buttonExport
STD_BITMAP_BUTTON * m_removeFieldButton
STD_BITMAP_BUTTON * m_browseButton
STD_BITMAP_BUTTON * m_sidebarButton
STD_BITMAP_BUTTON * m_copyVariantButton
wxTextCtrl * m_textOutput
STD_BITMAP_BUTTON * m_bRefresh
STD_BITMAP_BUTTON * m_renameFieldButton
STD_BITMAP_BUTTON * m_addFieldButton
wxTextCtrl * m_textStringDelimiter
wxChoice * m_cbBomPresets
wxListBox * m_variantListBox
wxTextCtrl * m_outputFileName
wxSplitterWindow * m_splitterMainWindow
STD_BITMAP_BUTTON * m_renameVariantButton
wxTextCtrl * m_textFieldDelimiter
wxCheckBox * m_groupSymbolsBox
wxTextCtrl * m_textRefRangeDelimiter
wxSplitterWindow * m_splitter_left
WX_GRID * m_viewControlsGrid
wxChoice * m_cbBomFmtPresets
wxTextCtrl * m_textRefDelimiter
void OnTableColSize(wxGridSizeEvent &event) override
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
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)
void setSideBarButtonLook(bool aIsLeftPanelCollapsed)
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 OnTableValueChanged(wxGridEvent &event) override
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
void OnFilterMouseMoved(wxMouseEvent &event) override
std::map< wxString, BOM_FMT_PRESET > m_bomFmtPresets
DIALOG_SYMBOL_FIELDS_TABLE(SCH_EDIT_FRAME *parent, JOB_EXPORT_SCH_BOM *aJob=nullptr)
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
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)
JOB_EXPORT_SCH_BOM * m_job
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 OnSizeViewControlsGrid(wxSizeEvent &event) override
void rebuildBomFmtPresetsWidget()
BOM_PRESET * m_lastSelectedBomPreset
void rebuildBomPresetsWidget()
BOM_PRESET * m_currentBomPreset
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.
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
wxArrayString GetVariantNamesForUI() const
Return an array of variant names for using in wxWidgets UI controls.
SCH_SHEET_PATH & CurrentSheet() const
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 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...
void GetSymbolsWithinPath(SCH_REFERENCE_LIST &aReferences, const SCH_SHEET_PATH &aSheetPath, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets that are contained wi...
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
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)
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
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.
#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()
KICOMMON_API wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
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.
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.
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.