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]()
335 m_parent->Schematic().AddListener(
this );
340 m_grid->EnableEditing(
false );
359 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
361 if(
m_grid->IsColShown( i ) )
363 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
378 m_grid->PopEventHandler(
true );
388 if( aIsLeftPanelCollapsed )
403 wxGridCellAttr* attr =
new wxGridCellAttr;
404 attr->SetReadOnly(
false );
428 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
429 attr->SetRenderer(
new wxGridCellNumberRenderer() );
434 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
447 attr->SetEditor(
m_grid->GetDefaultEditor() );
456 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
459 m_grid->AutoSizeColumns(
false );
461 bool sortAscending =
true;
463 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
489 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
499 int maxWidth = defaultDlgSize.x / 3;
501 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
511 m_grid->SetSortingColumn( sortCol, sortAscending );
517 if( !wxDialog::TransferDataToWindow() )
540 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
543 field.
name = fieldName;
544 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
547 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
568 fmtPreset.
name =
m_job->m_bomFmtPresetName;
587 wxCommandEvent
dummy;
590 if( selection.GetSize() == 1 )
602 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
604 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
609 if( ref.GetSymbol() == symbol )
623 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
629 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
633 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
634 m_grid->GoToCell( row, valueCol );
635 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
636 m_grid->GoToCell( row, refCol );
637 else if( anyCol != -1 )
638 m_grid->GoToCell( row, anyCol );
656 if( !
m_grid->CommitPendingChanges() )
659 if( !wxDialog::TransferDataFromWindow() )
670 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
674 if( !commit.
Empty() )
676 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
681 m_parent->SetCurrentSheet( currentSheet );
690 bool show,
bool groupBy,
bool addedByUser )
700 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
702 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
703 m_grid->ProcessTableMessage( msg );
706 [&]() -> std::pair<int, int>
717 auto addMandatoryField =
718 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
738 std::set<wxString> userFieldNames;
746 if( !field.IsMandatory() && !field.IsPrivate() )
747 userFieldNames.insert( field.GetName() );
751 for(
const wxString& fieldName : userFieldNames )
757 if( userFieldNames.count( tfn.m_Name ) == 0 )
765 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
767 if( dlg.ShowModal() != wxID_OK )
770 wxString fieldName = dlg.GetValue();
772 if( fieldName.IsEmpty() )
778 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
780 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
782 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
805 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
811 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
817 int col =
m_dataModel->GetFieldNameCol( fieldName );
837 if( selectedRows.empty() )
840 int row = selectedRows[0];
846 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
856 int col =
m_dataModel->GetFieldNameCol( fieldName );
857 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
859 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
861 if( dlg.ShowModal() != wxID_OK )
864 wxString newFieldName = dlg.GetValue();
867 if( newFieldName == fieldName )
871 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
873 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
882 if( labelIsAutogenerated )
906#if defined( __WXOSX__ )
907 wxPoint pos = aEvent.GetPosition();
908 wxRect ctrlRect =
m_filter->GetScreenRect();
909 int buttonWidth = ctrlRect.GetHeight();
912 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
913 SetCursor( wxCURSOR_ARROW );
914 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
915 SetCursor( wxCURSOR_ARROW );
917 SetCursor( wxCURSOR_IBEAM );
932 switch( aEvent.GetSelection() )
934 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
935 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
936 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
958 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
959 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
960 "symbols are included on export." ),
964 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
965 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
966 "are never included on export." ),
968 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
970 menu.AppendSeparator();
972 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
973 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
977 menu.Append( 4207,
_(
"Select on Cross-probe" ),
978 _(
"Select corresponding item on canvas when it is selected in the table" ),
983 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
985 if( menu_id == 0 || menu_id == 4204 )
993 else if( menu_id == 1 || menu_id == 4205 )
1001 else if( menu_id == 3 || menu_id == 4206 )
1008 else if( menu_id == 4 || menu_id == 4207 )
1020 int sortCol = aEvent.GetCol();
1021 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1033 if(
m_grid->IsSortingBy( sortCol ) )
1036 ascending = !
m_grid->IsSortOrderAscending();
1054 int origPos = aEvent.GetCol();
1059 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1061 if(
m_grid->IsColShown( i ) )
1063 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1071 int newPos =
m_grid->GetColPos( origPos );
1074 if( newPos < origPos )
1115 int row = aEvent.GetRow();
1117 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1119 switch( aEvent.GetCol() )
1125 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1130 m_grid->SetColLabelValue( dataCol, label );
1148 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1160 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1162 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1164 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1171 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1173 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1222 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1224 m_grid->ClearSelection();
1227 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1240 wxPoint pos = aEvent.GetPosition();
1242 m_grid->CalcUnscrolledPosition( pos.x, pos.y, &ux, &uy );
1243 int row =
m_grid->YToRow( uy );
1244 int col =
m_grid->XToCol( ux );
1247 if( row == wxNOT_FOUND || col == wxNOT_FOUND )
1249 m_grid->GetGridWindow()->UnsetToolTip();
1253 wxString rawValue =
m_dataModel->GetValue( row, col );
1255 if( rawValue.Contains( wxT(
"${" ) ) )
1257 m_grid->GetGridWindow()->SetToolTip( rawValue );
1261 m_grid->GetGridWindow()->UnsetToolTip();
1276 std::set<SCH_REFERENCE> refs;
1277 std::set<SCH_ITEM*> symbols;
1280 if( aEvent.Selecting() )
1282 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1289 symbols.insert( ref.GetSymbol() );
1296 if( refs.size() > 0 )
1300 wxString symbol_path = refs.begin()->GetFullPath();
1313 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1315 if( refs.size() > 0 )
1316 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1329 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1378 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1385 if( saveIncludeExcudedFromBOM )
1429 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1432 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1437 if( saveDlg.ShowModal() == wxID_CANCEL )
1441 wxFileName file = wxFileName( saveDlg.GetPath() );
1442 wxString defaultPath = fn.GetPathWithSep();
1444 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1446 if( !file.MakeRelativeTo( defaultPath ) )
1448 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1449 "file volume)!" ) );
1483 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1484 _(
"OK" ),
_(
"Cancel" ) )
1494 std::function<bool( wxString* )> textResolver =
1495 [&]( wxString* token ) ->
bool
1505 if(
path.IsEmpty() )
1507 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1514 wxFileName outputFile = wxFileName::FileName(
path );
1520 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1525 wxFFile out( outputFile.GetFullPath(),
"wb" );
1527 if( !out.IsOpened() )
1529 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1538 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1545 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1553 EndModal( wxID_CANCEL );
1570 m_job->m_bomFmtPresetName = wxEmptyString;
1575 m_job->m_bomPresetName = wxEmptyString;
1592 m_job->m_fieldsOrdered.clear();
1593 m_job->m_fieldsLabels.clear();
1594 m_job->m_fieldsGroupBy.clear();
1598 if( modelField.show )
1599 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1601 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1603 m_job->m_fieldsLabels.emplace_back( modelField.label );
1605 if( modelField.groupBy )
1606 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1611 if( !selectedVariant.IsEmpty() )
1612 m_job->m_variantNames.push_back( selectedVariant );
1614 EndModal( wxID_OK );
1631 m_grid->CommitPendingChanges(
true );
1647 m_parent->Schematic().RemoveListener(
this );
1650 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1652 if( wxWindow* parent = GetParent() )
1653 wxQueueEvent( parent, evt );
1659 std::vector<BOM_PRESET> ret;
1661 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1663 if( !pair.second.readOnly )
1664 ret.emplace_back( pair.second );
1676 for(
const BOM_PRESET& preset : aPresetList )
1694 wxCommandEvent
dummy;
1737 int default_idx = 0;
1741 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1766 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1768 const BOM_PRESET& preset = aPair.second;
1771 if( !( preset.sortAsc == current.sortAsc
1772 && preset.filterString == current.filterString
1773 && preset.groupSymbols == current.groupSymbols
1774 && preset.excludeDNP == current.excludeDNP
1775 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1786 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1790 std::vector<BOM_FIELD>
A,
B;
1792 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1794 if( field.show || field.groupBy )
1795 A.emplace_back( field );
1800 if( field.show || field.groupBy )
1801 B.emplace_back( field );
1807 if( it != m_bomPresets.end() )
1811 bool do_translate = it->second.readOnly;
1812 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1813 m_cbBomPresets->SetStringSelection(
text );
1817 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1820 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1829 wxString ui_label = aName;
1833 if( presetName == aName )
1835 if( preset.readOnly ==
true )
1836 ui_label = wxGetTranslation( aName );
1861 auto resetSelection =
1870 if(
index == count - 3 )
1876 else if(
index == count - 2 )
1884 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1886 if( dlg.ShowModal() != wxID_OK )
1892 name = dlg.GetValue();
1910 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1911 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1918 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1939 else if(
index == count - 1 )
1942 wxArrayString headers;
1943 std::vector<wxArrayString> items;
1945 headers.Add(
_(
"Presets" ) );
1949 if( !preset.readOnly )
1953 items.emplace_back( item );
1965 if( idx != wxNOT_FOUND )
2015 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
2017 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2038 int col =
m_dataModel->GetFieldNameCol( fieldName );
2042 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2047 std::string fieldNameStr( fieldName.ToUTF8() );
2050 const wxString& label =
m_dataModel->GetColLabelValue( col );
2052 m_grid->SetColLabelValue( col, label );
2067 bool groupBy =
m_dataModel->GetGroupColumn( col );
2091 std::vector<BOM_FMT_PRESET> ret;
2095 if( !preset.readOnly )
2096 ret.emplace_back( preset );
2126 wxCommandEvent
dummy;
2168 int default_idx = 0;
2197 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2199 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2200 && aPair.second.stringDelimiter == current.stringDelimiter
2201 && aPair.second.refDelimiter == current.refDelimiter
2202 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2203 && aPair.second.keepTabs == current.keepTabs
2204 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2211 bool do_translate = it->second.readOnly;
2212 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2231 wxString ui_label = aName;
2235 if( presetName == aName )
2237 if( preset.readOnly )
2238 ui_label = wxGetTranslation( aName );
2263 auto resetSelection =
2272 if(
index == count - 3 )
2278 else if(
index == count - 2 )
2286 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2288 if( dlg.ShowModal() != wxID_OK )
2294 name = dlg.GetValue();
2312 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2313 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2320 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2341 else if(
index == count - 1 )
2344 wxArrayString headers;
2345 std::vector<wxArrayString> items;
2347 headers.Add(
_(
"Presets" ) );
2349 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2351 if( !pair.second.readOnly )
2354 item.Add( pair.first );
2355 items.emplace_back( item );
2367 if( idx != wxNOT_FOUND )
2422 bool modified =
false;
2425 std::vector<BOM_PRESET> presets;
2429 if( !preset.readOnly )
2430 presets.emplace_back( preset );
2446 std::vector<BOM_FMT_PRESET> fmts;
2450 if( !preset.readOnly )
2451 fmts.emplace_back( preset );
2476 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2490 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2496 std::set<SCH_SYMBOL*> symbols;
2500 symbols.insert( ref.GetSymbol() );
2505 for(
SCH_FIELD& field : symbol->GetFields() )
2506 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2544 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2558 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2561 m_parent->Schematic().GetCurrentVariant() );
2565 std::set<SCH_SYMBOL*> symbols;
2569 symbols.insert( ref.GetSymbol() );
2574 for(
SCH_FIELD& field : symbol->GetFields() )
2575 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2593 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2607 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2615 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2623 std::set<wxString> selectedFullPaths;
2625 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2626 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2628 for(
size_t i = 0; i < topLeft.size(); ++i )
2630 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2633 selectedFullPaths.insert( ref.GetFullPath() );
2637 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2639 for(
int row : selectedRows )
2642 selectedFullPaths.insert( ref.GetFullPath() );
2645 int cursorRow =
m_grid->GetGridCursorRow();
2647 if( cursorRow >= 0 && selectedFullPaths.empty() )
2650 selectedFullPaths.insert( ref.GetFullPath() );
2653 return selectedFullPaths;
2659 if( aFullPaths.empty() )
2662 m_grid->ClearSelection();
2664 bool firstSelection =
true;
2666 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2668 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2672 if( aFullPaths.count( ref.GetFullPath() ) )
2674 m_grid->SelectRow( row,
true );
2676 if( firstSelection )
2678 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2679 firstSelection =
false;
2694 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2721 if( basePath.Path() == instance.m_Path )
2729 subSheets.push_back( sheetPath );
2747 if( !
m_parent->ShowAddVariantDialog() )
2750 wxArrayString ctrlContents;
2753 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2754 ctrlContents.Add( variant );
2759 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2763 if( newSelection != wxNOT_FOUND )
2775 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2777 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2778 10000, wxICON_ERROR );
2784 m_parent->Schematic().DeleteVariant( variantName );
2787 int newSelection = std::max( 0, selection - 1 );
2791 m_parent->SetCurrentVariant( selectedVariant );
2793 if(
m_grid->CommitPendingChanges(
true ) )
2795 m_dataModel->SetCurrentVariant( selectedVariant );
2806 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2815 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2817 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2818 10000, wxICON_ERROR );
2824 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2825 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2827 if( dlg.ShowModal() == wxID_CANCEL )
2830 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2833 if( newVariantName.IsEmpty() )
2835 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2842 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2844 10000, wxICON_ERROR );
2849 if( newVariantName == oldVariantName )
2853 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2855 if( existingName.CmpNoCase( newVariantName ) == 0
2856 && existingName.CmpNoCase( oldVariantName ) != 0 )
2858 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2860 0000, wxICON_ERROR );
2865 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2869 ctrlContents.Remove( oldVariantName );
2870 ctrlContents.Add( newVariantName );
2876 if( newSelection != wxNOT_FOUND )
2880 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2889 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2891 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2892 10000, wxICON_ERROR );
2898 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2899 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2901 if( dlg.ShowModal() == wxID_CANCEL )
2904 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2907 if( newVariantName.IsEmpty() )
2909 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2916 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2918 10000, wxICON_ERROR );
2922 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2926 ctrlContents.Add( newVariantName );
2932 if( newSelection != wxNOT_FOUND )
2936 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2942 wxString currentVariant;
2949 currentVariant =
m_parent->Schematic().GetCurrentVariant();
2951 if( currentVariant != selectedVariant )
2952 m_parent->SetCurrentVariant( selectedVariant );
2955 if( currentVariant != selectedVariant )
2957 m_grid->CommitPendingChanges(
true );
2963 if( !commit.
Empty() )
2965 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
2970 m_dataModel->SetCurrentVariant( selectedVariant );
2989 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
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)
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.