51#include <wx/textdlg.h>
52#include <wx/filedlg.h>
65#define COLUMN_MARGIN 4
67#define COLUMN_MARGIN 15
113 int col =
m_grid->GetGridCursorCol();
118 menu.AppendSeparator();
123 menu.AppendSeparator();
131 int row =
m_grid->GetGridCursorRow();
132 int col =
m_grid->GetGridCursorCol();
137 wxString fpid =
m_grid->GetCellValue( row, col );
141 if( frame->ShowModal( &fpid,
m_dlg ) )
142 m_grid->SetCellValue( row, col, fpid );
149 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
155 if( !
m_grid->CommitPendingChanges(
false ) )
163 m_dlg->ShowHideColumn( col, show );
165 wxString fieldName =
m_dataModel->GetColFieldName( col );
207 if(
resolver.ShowModal() != wxID_OK )
249 wxGridCellAttr* attr =
new wxGridCellAttr;
250 attr->SetReadOnly(
true );
253 attr =
new wxGridCellAttr;
254 attr->SetRenderer(
new wxGridCellBoolRenderer() );
256 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
259 attr =
new wxGridCellAttr;
260 attr->SetRenderer(
new wxGridCellBoolRenderer() );
262 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
268 m_filter->SetDescriptiveText(
_(
"Filter" ) );
270 attr =
new wxGridCellAttr;
274 m_grid->UseNativeColHeader(
true );
278 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
286 if( !
m_parent->Schematic().GetCurrentVariant().IsEmpty() )
290 if( toSelect == wxNOT_FOUND )
303 SetTitle(
m_job->GetSettingsDialogTitle() );
325 CallAfter( [
this, cfg]()
355 m_parent->Schematic().AddListener(
this );
360 m_grid->EnableEditing(
false );
379 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
381 if(
m_grid->IsColShown( i ) )
383 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
398 m_grid->PopEventHandler(
true );
408 if( aIsLeftPanelCollapsed )
423 wxGridCellAttr* attr =
new wxGridCellAttr;
424 attr->SetReadOnly(
false );
448 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
449 attr->SetRenderer(
new wxGridCellNumberRenderer() );
454 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
467 attr->SetEditor(
m_grid->GetDefaultEditor() );
476 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
479 m_grid->AutoSizeColumns(
false );
481 bool sortAscending =
true;
483 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
509 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
519 int maxWidth = defaultDlgSize.x / 3;
521 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
531 m_grid->SetSortingColumn( sortCol, sortAscending );
537 if( !wxDialog::TransferDataToWindow() )
560 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
563 field.
name = fieldName;
564 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
567 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
588 fmtPreset.
name =
m_job->m_bomFmtPresetName;
607 wxCommandEvent
dummy;
610 if( selection.GetSize() == 1 )
622 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
624 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
629 if( ref.GetSymbol() == symbol )
643 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
649 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
653 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
654 m_grid->GoToCell( row, valueCol );
655 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
656 m_grid->GoToCell( row, refCol );
657 else if( anyCol != -1 )
658 m_grid->GoToCell( row, anyCol );
676 if( !
m_grid->CommitPendingChanges() )
679 if( !wxDialog::TransferDataFromWindow() )
690 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
694 if( !commit.
Empty() )
696 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
701 m_parent->SetCurrentSheet( currentSheet );
710 bool show,
bool groupBy,
bool addedByUser )
720 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
722 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
723 m_grid->ProcessTableMessage( msg );
726 [&]() -> std::pair<int, int>
737 auto addMandatoryField =
738 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
758 auto caseInsensitiveLess = [](
const wxString& a,
const wxString& b )
760 return a.CmpNoCase( b ) < 0;
763 std::map<wxString, std::map<wxString, int>,
decltype( caseInsensitiveLess )> userFieldGroups( caseInsensitiveLess );
771 if( !field.IsMandatory() && !field.IsPrivate() )
772 userFieldGroups[field.GetName()][field.GetName()]++;
776 for(
const auto& [groupKey, exactCounts] : userFieldGroups )
778 wxString canonicalName;
782 canonicalName = tfn->m_Name;
788 for(
const auto& [
name, count] : exactCounts )
790 if( count > bestCount )
793 canonicalName =
name;
804 if( userFieldGroups.count( tfn.m_Name ) == 0 )
812 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
814 if( dlg.ShowModal() != wxID_OK )
817 wxString fieldName = dlg.GetValue();
819 if( fieldName.IsEmpty() )
825 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
827 if( fieldName.CmpNoCase(
m_dataModel->GetColFieldName( i ) ) == 0 )
829 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
852 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
858 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
864 int col =
m_dataModel->GetFieldNameCol( fieldName );
884 if( selectedRows.empty() )
887 int row = selectedRows[0];
893 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
903 int col =
m_dataModel->GetFieldNameCol( fieldName );
904 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
906 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
908 if( dlg.ShowModal() != wxID_OK )
911 wxString newFieldName = dlg.GetValue();
914 if( newFieldName == fieldName )
918 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
920 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
929 if( labelIsAutogenerated )
953#if defined( __WXOSX__ )
954 wxPoint pos = aEvent.GetPosition();
955 wxRect ctrlRect =
m_filter->GetScreenRect();
956 int buttonWidth = ctrlRect.GetHeight();
959 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
960 SetCursor( wxCURSOR_ARROW );
961 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
962 SetCursor( wxCURSOR_ARROW );
964 SetCursor( wxCURSOR_IBEAM );
979 switch( aEvent.GetSelection() )
981 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
982 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
983 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
1005 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
1006 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
1007 "symbols are included on export." ),
1009 menu.Check( 4204, !
m_dataModel->GetExcludeDNP() );
1011 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
1012 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
1013 "are never included on export." ),
1015 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
1017 menu.AppendSeparator();
1019 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1020 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
1024 menu.Append( 4207,
_(
"Select on Cross-probe" ),
1025 _(
"Select corresponding item on canvas when it is selected in the table" ),
1030 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1032 if( menu_id == 0 || menu_id == 4204 )
1040 else if( menu_id == 1 || menu_id == 4205 )
1048 else if( menu_id == 3 || menu_id == 4206 )
1055 else if( menu_id == 4 || menu_id == 4207 )
1067 int sortCol = aEvent.GetCol();
1068 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1080 if(
m_grid->IsSortingBy( sortCol ) )
1083 ascending = !
m_grid->IsSortOrderAscending();
1101 int origPos = aEvent.GetCol();
1106 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1108 if(
m_grid->IsColShown( i ) )
1110 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1118 int newPos =
m_grid->GetColPos( origPos );
1121 if( newPos < origPos )
1162 int row = aEvent.GetRow();
1164 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1166 switch( aEvent.GetCol() )
1172 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1177 m_grid->SetColLabelValue( dataCol, label );
1195 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1207 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1209 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1211 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1218 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1220 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1269 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1271 m_grid->ClearSelection();
1274 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1287 wxPoint pos = aEvent.GetPosition();
1289 m_grid->CalcUnscrolledPosition( pos.x, pos.y, &ux, &uy );
1290 int row =
m_grid->YToRow( uy );
1291 int col =
m_grid->XToCol( ux );
1294 if( row == wxNOT_FOUND || col == wxNOT_FOUND )
1296 m_grid->GetGridWindow()->UnsetToolTip();
1300 wxString rawValue =
m_dataModel->GetValue( row, col );
1302 if( rawValue.Contains( wxT(
"${" ) ) )
1304 m_grid->GetGridWindow()->SetToolTip( rawValue );
1308 m_grid->GetGridWindow()->UnsetToolTip();
1323 std::set<SCH_REFERENCE> refs;
1324 std::set<SCH_ITEM*> symbols;
1327 if( aEvent.Selecting() )
1329 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1336 symbols.insert( ref.GetSymbol() );
1343 if( refs.size() > 0 )
1347 wxString symbol_path = refs.begin()->GetFullPath();
1360 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1362 if( refs.size() > 0 )
1363 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1376 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1425 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1432 if( saveIncludeExcudedFromBOM )
1476 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1479 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1484 if( saveDlg.ShowModal() == wxID_CANCEL )
1488 wxFileName file = wxFileName( saveDlg.GetPath() );
1489 wxString defaultPath = fn.GetPathWithSep();
1491 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1493 if( !file.MakeRelativeTo( defaultPath ) )
1495 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1496 "file volume)!" ) );
1530 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1531 _(
"OK" ),
_(
"Cancel" ) )
1541 std::function<bool( wxString* )> textResolver =
1542 [&]( wxString* token ) ->
bool
1547 return schematic.ResolveTextVar( &schematic.CurrentSheet(), token, 0 );
1552 if(
path.IsEmpty() )
1554 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1561 wxFileName outputFile = wxFileName::FileName(
path );
1567 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1572 wxFFile out( outputFile.GetFullPath(),
"wb" );
1574 if( !out.IsOpened() )
1576 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1585 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1592 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1600 EndModal( wxID_CANCEL );
1617 m_job->m_bomFmtPresetName = wxEmptyString;
1622 m_job->m_bomPresetName = wxEmptyString;
1639 m_job->m_fieldsOrdered.clear();
1640 m_job->m_fieldsLabels.clear();
1641 m_job->m_fieldsGroupBy.clear();
1645 if( modelField.show )
1646 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1648 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1650 m_job->m_fieldsLabels.emplace_back( modelField.label );
1652 if( modelField.groupBy )
1653 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1658 if( !selectedVariant.IsEmpty() )
1659 m_job->m_variantNames.push_back( selectedVariant );
1661 EndModal( wxID_OK );
1678 m_grid->CommitPendingChanges(
true );
1694 m_parent->Schematic().RemoveListener(
this );
1697 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1699 if( wxWindow* parent = GetParent() )
1700 wxQueueEvent( parent, evt );
1706 std::vector<BOM_PRESET> ret;
1708 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1710 if( !pair.second.readOnly )
1711 ret.emplace_back( pair.second );
1723 for(
const BOM_PRESET& preset : aPresetList )
1741 wxCommandEvent
dummy;
1784 int default_idx = 0;
1788 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1813 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1815 const BOM_PRESET& preset = aPair.second;
1818 if( !( preset.sortAsc == current.sortAsc
1819 && preset.filterString == current.filterString
1820 && preset.groupSymbols == current.groupSymbols
1821 && preset.excludeDNP == current.excludeDNP
1822 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1833 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1837 std::vector<BOM_FIELD>
A,
B;
1839 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1841 if( field.show || field.groupBy )
1842 A.emplace_back( field );
1847 if( field.show || field.groupBy )
1848 B.emplace_back( field );
1854 if( it != m_bomPresets.end() )
1858 bool do_translate = it->second.readOnly;
1859 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1860 m_cbBomPresets->SetStringSelection(
text );
1864 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1867 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1876 wxString ui_label = aName;
1880 if( presetName == aName )
1882 if( preset.readOnly ==
true )
1883 ui_label = wxGetTranslation( aName );
1908 auto resetSelection =
1917 if(
index == count - 3 )
1923 else if(
index == count - 2 )
1931 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1933 if( dlg.ShowModal() != wxID_OK )
1939 name = dlg.GetValue();
1957 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1958 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1965 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1986 else if(
index == count - 1 )
1989 wxArrayString headers;
1990 std::vector<wxArrayString> items;
1992 headers.Add(
_(
"Presets" ) );
1996 if( !preset.readOnly )
2000 items.emplace_back( item );
2012 if( idx != wxNOT_FOUND )
2062 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
2064 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2085 int col =
m_dataModel->GetFieldNameCol( fieldName );
2089 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2094 std::string fieldNameStr( fieldName.ToUTF8() );
2097 const wxString& label =
m_dataModel->GetColLabelValue( col );
2099 m_grid->SetColLabelValue( col, label );
2114 bool groupBy =
m_dataModel->GetGroupColumn( col );
2138 std::vector<BOM_FMT_PRESET> ret;
2142 if( !preset.readOnly )
2143 ret.emplace_back( preset );
2173 wxCommandEvent
dummy;
2215 int default_idx = 0;
2244 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2246 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2247 && aPair.second.stringDelimiter == current.stringDelimiter
2248 && aPair.second.refDelimiter == current.refDelimiter
2249 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2250 && aPair.second.keepTabs == current.keepTabs
2251 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2258 bool do_translate = it->second.readOnly;
2259 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2278 wxString ui_label = aName;
2282 if( presetName == aName )
2284 if( preset.readOnly )
2285 ui_label = wxGetTranslation( aName );
2310 auto resetSelection =
2319 if(
index == count - 3 )
2325 else if(
index == count - 2 )
2333 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2335 if( dlg.ShowModal() != wxID_OK )
2341 name = dlg.GetValue();
2359 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2360 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2367 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2388 else if(
index == count - 1 )
2391 wxArrayString headers;
2392 std::vector<wxArrayString> items;
2394 headers.Add(
_(
"Presets" ) );
2396 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2398 if( !pair.second.readOnly )
2401 item.Add( pair.first );
2402 items.emplace_back( item );
2414 if( idx != wxNOT_FOUND )
2469 bool modified =
false;
2472 std::vector<BOM_PRESET> presets;
2476 if( !preset.readOnly )
2477 presets.emplace_back( preset );
2493 std::vector<BOM_FMT_PRESET> fmts;
2497 if( !preset.readOnly )
2498 fmts.emplace_back( preset );
2537 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2543 std::set<SCH_SYMBOL*> symbols;
2547 symbols.insert( ref.GetSymbol() );
2552 for(
SCH_FIELD& field : symbol->GetFields() )
2553 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2605 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2608 m_parent->Schematic().GetCurrentVariant() );
2612 std::set<SCH_SYMBOL*> symbols;
2616 symbols.insert( ref.GetSymbol() );
2621 for(
SCH_FIELD& field : symbol->GetFields() )
2622 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2640 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2654 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2662 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2670 std::set<wxString> selectedFullPaths;
2672 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2673 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2675 for(
size_t i = 0; i < topLeft.size(); ++i )
2677 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2680 selectedFullPaths.insert( ref.GetFullPath() );
2684 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2686 for(
int row : selectedRows )
2689 selectedFullPaths.insert( ref.GetFullPath() );
2692 int cursorRow =
m_grid->GetGridCursorRow();
2694 if( cursorRow >= 0 && selectedFullPaths.empty() )
2697 selectedFullPaths.insert( ref.GetFullPath() );
2700 return selectedFullPaths;
2706 if( aFullPaths.empty() )
2709 m_grid->ClearSelection();
2711 bool firstSelection =
true;
2713 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2715 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2719 if( aFullPaths.count( ref.GetFullPath() ) )
2721 m_grid->SelectRow( row,
true );
2723 if( firstSelection )
2725 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2726 firstSelection =
false;
2741 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2768 if( basePath.Path() == instance.m_Path )
2776 subSheets.push_back( sheetPath );
2794 if( !
m_parent->ShowAddVariantDialog() )
2797 wxArrayString ctrlContents;
2800 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2801 ctrlContents.Add( variant );
2806 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2810 if( newSelection != wxNOT_FOUND )
2822 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2824 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2825 10000, wxICON_ERROR );
2831 m_parent->Schematic().DeleteVariant( variantName );
2834 int newSelection = std::max( 0, selection - 1 );
2838 m_parent->SetCurrentVariant( selectedVariant );
2840 if(
m_grid->CommitPendingChanges(
true ) )
2842 m_dataModel->SetCurrentVariant( selectedVariant );
2853 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2862 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2864 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2865 10000, wxICON_ERROR );
2871 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2872 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2874 if( dlg.ShowModal() == wxID_CANCEL )
2877 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2880 if( newVariantName.IsEmpty() )
2882 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2889 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2891 10000, wxICON_ERROR );
2896 if( newVariantName == oldVariantName )
2900 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2902 if( existingName.CmpNoCase( newVariantName ) == 0
2903 && existingName.CmpNoCase( oldVariantName ) != 0 )
2905 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2907 0000, wxICON_ERROR );
2912 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2916 ctrlContents.Remove( oldVariantName );
2917 ctrlContents.Add( newVariantName );
2923 if( newSelection != wxNOT_FOUND )
2927 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2936 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2938 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2939 10000, wxICON_ERROR );
2945 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2946 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2948 if( dlg.ShowModal() == wxID_CANCEL )
2951 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2954 if( newVariantName.IsEmpty() )
2956 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2963 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2965 10000, wxICON_ERROR );
2969 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2973 ctrlContents.Add( newVariantName );
2979 if( newSelection != wxNOT_FOUND )
2983 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2991 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2993 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot edit the default variant description." ), 10000,
2999 wxString currentDesc =
m_parent->Schematic().GetVariantDescription( variantName );
3001 wxDialog dlg(
this, wxID_ANY, wxString::Format(
_(
"Edit Description for '%s'" ), variantName ), wxDefaultPosition,
3002 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
3004 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
3006 wxStaticText* label =
new wxStaticText( &dlg, wxID_ANY,
_(
"Description:" ) );
3007 mainSizer->Add( label, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 10 );
3009 mainSizer->AddSpacer( 3 );
3011 wxTextCtrl* descCtrl =
3012 new wxTextCtrl( &dlg, wxID_ANY, currentDesc, wxDefaultPosition, wxSize( 300, 60 ), wxTE_MULTILINE );
3013 mainSizer->Add( descCtrl, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 10 );
3015 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
3016 btnSizer->AddButton(
new wxButton( &dlg, wxID_OK ) );
3017 btnSizer->AddButton(
new wxButton( &dlg, wxID_CANCEL ) );
3018 btnSizer->Realize();
3019 mainSizer->Add( btnSizer, 0, wxALL | wxALIGN_RIGHT, 5 );
3021 dlg.SetSizer( mainSizer );
3025 if( dlg.ShowModal() == wxID_CANCEL )
3028 wxString newDesc = descCtrl->GetValue().Trim().Trim(
false );
3030 m_parent->Schematic().SetVariantDescription( variantName, newDesc );
3037 wxString currentVariant;
3044 currentVariant =
m_parent->Schematic().GetCurrentVariant();
3046 if( currentVariant != selectedVariant )
3047 m_parent->SetCurrentVariant( selectedVariant );
3050 if( currentVariant != selectedVariant )
3052 m_grid->CommitPendingChanges(
true );
3058 if( !commit.
Empty() )
3060 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
3065 m_dataModel->SetCurrentVariant( selectedVariant );
3084 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 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...
wxCheckBox * m_checkKeepLineBreaks
STD_BITMAP_BUTTON * m_deleteVariantButton
STD_BITMAP_BUTTON * m_bRefreshPreview
STD_BITMAP_BUTTON * m_editVariantDescButton
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
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.
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 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
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.
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()
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.
@ 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.
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.