50#include <wx/textdlg.h>
51#include <wx/filedlg.h>
63#define COLUMN_MARGIN 4
65#define COLUMN_MARGIN 15
111 int col =
m_grid->GetGridCursorCol();
116 menu.AppendSeparator();
121 menu.AppendSeparator();
129 int row =
m_grid->GetGridCursorRow();
130 int col =
m_grid->GetGridCursorCol();
135 wxString fpid =
m_grid->GetCellValue( row, col );
139 if( frame->ShowModal( &fpid,
m_dlg ) )
140 m_grid->SetCellValue( row, col, fpid );
147 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
153 if( !
m_grid->CommitPendingChanges(
false ) )
161 m_dlg->ShowHideColumn( col, show );
163 wxString fieldName =
m_dataModel->GetColFieldName( col );
228 wxGridCellAttr* attr =
new wxGridCellAttr;
229 attr->SetReadOnly(
true );
232 attr =
new wxGridCellAttr;
233 attr->SetRenderer(
new wxGridCellBoolRenderer() );
235 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
238 attr =
new wxGridCellAttr;
239 attr->SetRenderer(
new wxGridCellBoolRenderer() );
241 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
247 m_filter->SetDescriptiveText(
_(
"Filter" ) );
249 attr =
new wxGridCellAttr;
253 m_grid->UseNativeColHeader(
true );
257 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
265 if( !
m_parent->Schematic().GetCurrentVariant().IsEmpty() )
269 if( toSelect == wxNOT_FOUND )
282 SetTitle(
m_job->GetSettingsDialogTitle() );
304 CallAfter( [
this, cfg]()
333 m_parent->Schematic().AddListener(
this );
338 m_grid->EnableEditing(
false );
357 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
359 if(
m_grid->IsColShown( i ) )
361 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
375 m_grid->PopEventHandler(
true );
385 if( aIsLeftPanelCollapsed )
400 wxGridCellAttr* attr =
new wxGridCellAttr;
401 attr->SetReadOnly(
false );
425 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
426 attr->SetRenderer(
new wxGridCellNumberRenderer() );
431 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
444 attr->SetEditor(
m_grid->GetDefaultEditor() );
453 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
456 m_grid->AutoSizeColumns(
false );
458 bool sortAscending =
true;
460 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
486 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
496 int maxWidth = defaultDlgSize.x / 3;
498 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
508 m_grid->SetSortingColumn( sortCol, sortAscending );
514 if( !wxDialog::TransferDataToWindow() )
537 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
540 field.
name = fieldName;
541 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
544 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
565 fmtPreset.
name =
m_job->m_bomFmtPresetName;
584 wxCommandEvent
dummy;
587 if( selection.GetSize() == 1 )
599 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
601 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
606 if( ref.GetSymbol() == symbol )
620 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
626 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
630 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
631 m_grid->GoToCell( row, valueCol );
632 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
633 m_grid->GoToCell( row, refCol );
634 else if( anyCol != -1 )
635 m_grid->GoToCell( row, anyCol );
653 if( !
m_grid->CommitPendingChanges() )
656 if( !wxDialog::TransferDataFromWindow() )
667 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
671 if( !commit.
Empty() )
673 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
678 m_parent->SetCurrentSheet( currentSheet );
687 bool show,
bool groupBy,
bool addedByUser )
697 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
699 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
700 m_grid->ProcessTableMessage( msg );
703 [&]() -> std::pair<int, int>
714 auto addMandatoryField =
715 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
735 std::set<wxString> userFieldNames;
743 if( !field.IsMandatory() && !field.IsPrivate() )
744 userFieldNames.insert( field.GetName() );
748 for(
const wxString& fieldName : userFieldNames )
754 if( userFieldNames.count( tfn.m_Name ) == 0 )
762 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
764 if( dlg.ShowModal() != wxID_OK )
767 wxString fieldName = dlg.GetValue();
769 if( fieldName.IsEmpty() )
775 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
777 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
779 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
802 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
808 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
814 int col =
m_dataModel->GetFieldNameCol( fieldName );
834 if( selectedRows.empty() )
837 int row = selectedRows[0];
843 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
853 int col =
m_dataModel->GetFieldNameCol( fieldName );
854 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
856 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
858 if( dlg.ShowModal() != wxID_OK )
861 wxString newFieldName = dlg.GetValue();
864 if( newFieldName == fieldName )
868 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
870 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
879 if( labelIsAutogenerated )
903#if defined( __WXOSX__ )
904 wxPoint pos = aEvent.GetPosition();
905 wxRect ctrlRect =
m_filter->GetScreenRect();
906 int buttonWidth = ctrlRect.GetHeight();
909 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
910 SetCursor( wxCURSOR_ARROW );
911 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
912 SetCursor( wxCURSOR_ARROW );
914 SetCursor( wxCURSOR_IBEAM );
929 switch( aEvent.GetSelection() )
931 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
932 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
933 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
955 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
956 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
957 "symbols are included on export." ),
961 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
962 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
963 "are never included on export." ),
965 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
967 menu.AppendSeparator();
969 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
970 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
974 menu.Append( 4207,
_(
"Select on Cross-probe" ),
975 _(
"Select corresponding item on canvas when it is selected in the table" ),
980 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
982 if( menu_id == 0 || menu_id == 4204 )
990 else if( menu_id == 1 || menu_id == 4205 )
998 else if( menu_id == 3 || menu_id == 4206 )
1005 else if( menu_id == 4 || menu_id == 4207 )
1017 int sortCol = aEvent.GetCol();
1018 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1030 if(
m_grid->IsSortingBy( sortCol ) )
1033 ascending = !
m_grid->IsSortOrderAscending();
1051 int origPos = aEvent.GetCol();
1056 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1058 if(
m_grid->IsColShown( i ) )
1060 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1068 int newPos =
m_grid->GetColPos( origPos );
1071 if( newPos < origPos )
1112 int row = aEvent.GetRow();
1114 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1116 switch( aEvent.GetCol() )
1122 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1127 m_grid->SetColLabelValue( dataCol, label );
1145 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1157 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1159 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1161 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1168 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1170 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1219 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1221 m_grid->ClearSelection();
1224 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1243 std::set<SCH_REFERENCE> refs;
1244 std::set<SCH_ITEM*> symbols;
1247 if( aEvent.Selecting() )
1249 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1256 symbols.insert( ref.GetSymbol() );
1263 if( refs.size() > 0 )
1267 wxString symbol_path = refs.begin()->GetFullPath();
1280 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1282 if( refs.size() > 0 )
1283 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1296 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1345 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1352 if( saveIncludeExcudedFromBOM )
1396 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1399 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1404 if( saveDlg.ShowModal() == wxID_CANCEL )
1408 wxFileName file = wxFileName( saveDlg.GetPath() );
1409 wxString defaultPath = fn.GetPathWithSep();
1411 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1413 if( !file.MakeRelativeTo( defaultPath ) )
1415 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1416 "file volume)!" ) );
1450 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1451 _(
"OK" ),
_(
"Cancel" ) )
1461 std::function<bool( wxString* )> textResolver =
1462 [&]( wxString* token ) ->
bool
1472 if(
path.IsEmpty() )
1474 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1481 wxFileName outputFile = wxFileName::FileName(
path );
1487 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1492 wxFFile out( outputFile.GetFullPath(),
"wb" );
1494 if( !out.IsOpened() )
1496 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1505 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1512 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1520 EndModal( wxID_CANCEL );
1537 m_job->m_bomFmtPresetName = wxEmptyString;
1542 m_job->m_bomPresetName = wxEmptyString;
1559 m_job->m_fieldsOrdered.clear();
1560 m_job->m_fieldsLabels.clear();
1561 m_job->m_fieldsGroupBy.clear();
1565 if( modelField.show )
1566 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1568 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1570 m_job->m_fieldsLabels.emplace_back( modelField.label );
1572 if( modelField.groupBy )
1573 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1578 if( !selectedVariant.IsEmpty() )
1579 m_job->m_variantNames.push_back( selectedVariant );
1581 EndModal( wxID_OK );
1598 m_grid->CommitPendingChanges(
true );
1614 m_parent->Schematic().RemoveListener(
this );
1617 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1619 if( wxWindow* parent = GetParent() )
1620 wxQueueEvent( parent, evt );
1626 std::vector<BOM_PRESET> ret;
1628 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1630 if( !pair.second.readOnly )
1631 ret.emplace_back( pair.second );
1643 for(
const BOM_PRESET& preset : aPresetList )
1661 wxCommandEvent
dummy;
1704 int default_idx = 0;
1708 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1733 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1735 const BOM_PRESET& preset = aPair.second;
1738 if( !( preset.sortAsc == current.sortAsc
1739 && preset.filterString == current.filterString
1740 && preset.groupSymbols == current.groupSymbols
1741 && preset.excludeDNP == current.excludeDNP
1742 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1753 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1757 std::vector<BOM_FIELD>
A,
B;
1759 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1761 if( field.show || field.groupBy )
1762 A.emplace_back( field );
1767 if( field.show || field.groupBy )
1768 B.emplace_back( field );
1774 if( it != m_bomPresets.end() )
1778 bool do_translate = it->second.readOnly;
1779 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1780 m_cbBomPresets->SetStringSelection(
text );
1784 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1787 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1796 wxString ui_label = aName;
1800 if( presetName == aName )
1802 if( preset.readOnly ==
true )
1803 ui_label = wxGetTranslation( aName );
1828 auto resetSelection =
1837 if(
index == count - 3 )
1843 else if(
index == count - 2 )
1851 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1853 if( dlg.ShowModal() != wxID_OK )
1859 name = dlg.GetValue();
1877 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1878 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1885 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1906 else if(
index == count - 1 )
1909 wxArrayString headers;
1910 std::vector<wxArrayString> items;
1912 headers.Add(
_(
"Presets" ) );
1916 if( !preset.readOnly )
1920 items.emplace_back( item );
1932 if( idx != wxNOT_FOUND )
1982 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
1984 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2005 int col =
m_dataModel->GetFieldNameCol( fieldName );
2009 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2014 std::string fieldNameStr( fieldName.ToUTF8() );
2017 const wxString& label =
m_dataModel->GetColLabelValue( col );
2019 m_grid->SetColLabelValue( col, label );
2034 bool groupBy =
m_dataModel->GetGroupColumn( col );
2058 std::vector<BOM_FMT_PRESET> ret;
2062 if( !preset.readOnly )
2063 ret.emplace_back( preset );
2093 wxCommandEvent
dummy;
2135 int default_idx = 0;
2164 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2166 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2167 && aPair.second.stringDelimiter == current.stringDelimiter
2168 && aPair.second.refDelimiter == current.refDelimiter
2169 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2170 && aPair.second.keepTabs == current.keepTabs
2171 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2178 bool do_translate = it->second.readOnly;
2179 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2198 wxString ui_label = aName;
2202 if( presetName == aName )
2204 if( preset.readOnly )
2205 ui_label = wxGetTranslation( aName );
2230 auto resetSelection =
2239 if(
index == count - 3 )
2245 else if(
index == count - 2 )
2253 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2255 if( dlg.ShowModal() != wxID_OK )
2261 name = dlg.GetValue();
2279 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2280 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2287 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2308 else if(
index == count - 1 )
2311 wxArrayString headers;
2312 std::vector<wxArrayString> items;
2314 headers.Add(
_(
"Presets" ) );
2316 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2318 if( !pair.second.readOnly )
2321 item.Add( pair.first );
2322 items.emplace_back( item );
2334 if( idx != wxNOT_FOUND )
2389 bool modified =
false;
2392 std::vector<BOM_PRESET> presets;
2396 if( !preset.readOnly )
2397 presets.emplace_back( preset );
2413 std::vector<BOM_FMT_PRESET> fmts;
2417 if( !preset.readOnly )
2418 fmts.emplace_back( preset );
2443 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2457 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2463 std::set<SCH_SYMBOL*> symbols;
2467 symbols.insert( ref.GetSymbol() );
2472 for(
SCH_FIELD& field : symbol->GetFields() )
2473 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2511 m_parent->Schematic().Hierarchy().GetSymbols( allRefs );
2525 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2528 m_parent->Schematic().GetCurrentVariant() );
2532 std::set<SCH_SYMBOL*> symbols;
2536 symbols.insert( ref.GetSymbol() );
2541 for(
SCH_FIELD& field : symbol->GetFields() )
2542 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2560 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2574 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2582 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2590 std::set<wxString> selectedFullPaths;
2592 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2593 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2595 for(
size_t i = 0; i < topLeft.size(); ++i )
2597 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2600 selectedFullPaths.insert( ref.GetFullPath() );
2604 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2606 for(
int row : selectedRows )
2609 selectedFullPaths.insert( ref.GetFullPath() );
2612 int cursorRow =
m_grid->GetGridCursorRow();
2614 if( cursorRow >= 0 && selectedFullPaths.empty() )
2617 selectedFullPaths.insert( ref.GetFullPath() );
2620 return selectedFullPaths;
2626 if( aFullPaths.empty() )
2629 m_grid->ClearSelection();
2631 bool firstSelection =
true;
2633 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2635 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2639 if( aFullPaths.count( ref.GetFullPath() ) )
2641 m_grid->SelectRow( row,
true );
2643 if( firstSelection )
2645 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2646 firstSelection =
false;
2661 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2688 if( basePath.Path() == instance.m_Path )
2696 subSheets.push_back( sheetPath );
2714 if( !
m_parent->ShowAddVariantDialog() )
2717 wxArrayString ctrlContents;
2720 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2721 ctrlContents.Add( variant );
2726 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2730 if( newSelection != wxNOT_FOUND )
2742 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2744 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2745 10000, wxICON_ERROR );
2751 m_parent->Schematic().DeleteVariant( variantName );
2753 int newSelection = std::max( 0, selection - 1 );
2757 m_parent->SetCurrentVariant( selectedVariant );
2759 if(
m_grid->CommitPendingChanges(
true ) )
2761 m_dataModel->SetCurrentVariant( selectedVariant );
2772 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2781 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2783 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2784 10000, wxICON_ERROR );
2790 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2791 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2793 if( dlg.ShowModal() == wxID_CANCEL )
2796 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2799 if( newVariantName.IsEmpty() )
2801 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2808 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2810 10000, wxICON_ERROR );
2815 if( newVariantName == oldVariantName )
2819 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2821 if( existingName.CmpNoCase( newVariantName ) == 0
2822 && existingName.CmpNoCase( oldVariantName ) != 0 )
2824 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2826 0000, wxICON_ERROR );
2831 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2834 ctrlContents.Remove( oldVariantName );
2835 ctrlContents.Add( newVariantName );
2841 if( newSelection != wxNOT_FOUND )
2845 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2854 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2856 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2857 10000, wxICON_ERROR );
2863 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2864 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2866 if( dlg.ShowModal() == wxID_CANCEL )
2869 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2872 if( newVariantName.IsEmpty() )
2874 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2881 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2883 10000, wxICON_ERROR );
2887 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2890 ctrlContents.Add( newVariantName );
2896 if( newSelection != wxNOT_FOUND )
2900 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2906 wxString currentVariant;
2913 currentVariant =
m_parent->Schematic().GetCurrentVariant();
2915 if( currentVariant != selectedVariant )
2916 m_parent->SetCurrentVariant( selectedVariant );
2919 if( currentVariant != selectedVariant )
2921 if(
m_grid->CommitPendingChanges(
true ) )
2924 m_dataModel->SetCurrentVariant( selectedVariant );
2948 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.