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 );
230 wxGridCellAttr* attr =
new wxGridCellAttr;
231 attr->SetReadOnly(
true );
234 attr =
new wxGridCellAttr;
235 attr->SetRenderer(
new wxGridCellBoolRenderer() );
237 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
240 attr =
new wxGridCellAttr;
241 attr->SetRenderer(
new wxGridCellBoolRenderer() );
243 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
249 m_filter->SetDescriptiveText(
_(
"Filter" ) );
251 attr =
new wxGridCellAttr;
255 m_grid->UseNativeColHeader(
true );
259 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
267 if( !
m_parent->Schematic().GetCurrentVariant().IsEmpty() )
271 if( toSelect == wxNOT_FOUND )
284 SetTitle(
m_job->GetSettingsDialogTitle() );
306 CallAfter( [
this, cfg]()
336 m_parent->Schematic().AddListener(
this );
341 m_grid->EnableEditing(
false );
360 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
362 if(
m_grid->IsColShown( i ) )
364 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
379 m_grid->PopEventHandler(
true );
389 if( aIsLeftPanelCollapsed )
404 wxGridCellAttr* attr =
new wxGridCellAttr;
405 attr->SetReadOnly(
false );
429 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
430 attr->SetRenderer(
new wxGridCellNumberRenderer() );
435 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
448 attr->SetEditor(
m_grid->GetDefaultEditor() );
457 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
460 m_grid->AutoSizeColumns(
false );
462 bool sortAscending =
true;
464 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
490 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
500 int maxWidth = defaultDlgSize.x / 3;
502 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
512 m_grid->SetSortingColumn( sortCol, sortAscending );
518 if( !wxDialog::TransferDataToWindow() )
541 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
544 field.
name = fieldName;
545 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
548 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
569 fmtPreset.
name =
m_job->m_bomFmtPresetName;
588 wxCommandEvent
dummy;
591 if( selection.GetSize() == 1 )
603 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
605 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
610 if( ref.GetSymbol() == symbol )
624 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
630 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
634 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
635 m_grid->GoToCell( row, valueCol );
636 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
637 m_grid->GoToCell( row, refCol );
638 else if( anyCol != -1 )
639 m_grid->GoToCell( row, anyCol );
657 if( !
m_grid->CommitPendingChanges() )
660 if( !wxDialog::TransferDataFromWindow() )
671 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
675 if( !commit.
Empty() )
677 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
682 m_parent->SetCurrentSheet( currentSheet );
691 bool show,
bool groupBy,
bool addedByUser )
701 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
703 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
704 m_grid->ProcessTableMessage( msg );
707 [&]() -> std::pair<int, int>
718 auto addMandatoryField =
719 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
739 std::set<wxString> userFieldNames;
747 if( !field.IsMandatory() && !field.IsPrivate() )
748 userFieldNames.insert( field.GetName() );
752 for(
const wxString& fieldName : userFieldNames )
758 if( userFieldNames.count( tfn.m_Name ) == 0 )
766 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
768 if( dlg.ShowModal() != wxID_OK )
771 wxString fieldName = dlg.GetValue();
773 if( fieldName.IsEmpty() )
779 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
781 if( fieldName.CmpNoCase(
m_dataModel->GetColFieldName( i ) ) == 0 )
783 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
806 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
812 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
818 int col =
m_dataModel->GetFieldNameCol( fieldName );
838 if( selectedRows.empty() )
841 int row = selectedRows[0];
847 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
857 int col =
m_dataModel->GetFieldNameCol( fieldName );
858 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
860 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
862 if( dlg.ShowModal() != wxID_OK )
865 wxString newFieldName = dlg.GetValue();
868 if( newFieldName == fieldName )
872 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
874 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
883 if( labelIsAutogenerated )
907#if defined( __WXOSX__ )
908 wxPoint pos = aEvent.GetPosition();
909 wxRect ctrlRect =
m_filter->GetScreenRect();
910 int buttonWidth = ctrlRect.GetHeight();
913 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
914 SetCursor( wxCURSOR_ARROW );
915 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
916 SetCursor( wxCURSOR_ARROW );
918 SetCursor( wxCURSOR_IBEAM );
933 switch( aEvent.GetSelection() )
935 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
936 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
937 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
959 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
960 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
961 "symbols are included on export." ),
965 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
966 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
967 "are never included on export." ),
969 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
971 menu.AppendSeparator();
973 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
974 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
978 menu.Append( 4207,
_(
"Select on Cross-probe" ),
979 _(
"Select corresponding item on canvas when it is selected in the table" ),
984 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
986 if( menu_id == 0 || menu_id == 4204 )
994 else if( menu_id == 1 || menu_id == 4205 )
1002 else if( menu_id == 3 || menu_id == 4206 )
1009 else if( menu_id == 4 || menu_id == 4207 )
1021 int sortCol = aEvent.GetCol();
1022 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1034 if(
m_grid->IsSortingBy( sortCol ) )
1037 ascending = !
m_grid->IsSortOrderAscending();
1055 int origPos = aEvent.GetCol();
1060 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1062 if(
m_grid->IsColShown( i ) )
1064 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1072 int newPos =
m_grid->GetColPos( origPos );
1075 if( newPos < origPos )
1116 int row = aEvent.GetRow();
1118 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1120 switch( aEvent.GetCol() )
1126 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1131 m_grid->SetColLabelValue( dataCol, label );
1149 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1161 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1163 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1165 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1172 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1174 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1223 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1225 m_grid->ClearSelection();
1228 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1241 wxPoint pos = aEvent.GetPosition();
1243 m_grid->CalcUnscrolledPosition( pos.x, pos.y, &ux, &uy );
1244 int row =
m_grid->YToRow( uy );
1245 int col =
m_grid->XToCol( ux );
1248 if( row == wxNOT_FOUND || col == wxNOT_FOUND )
1250 m_grid->GetGridWindow()->UnsetToolTip();
1254 wxString rawValue =
m_dataModel->GetValue( row, col );
1256 if( rawValue.Contains( wxT(
"${" ) ) )
1258 m_grid->GetGridWindow()->SetToolTip( rawValue );
1262 m_grid->GetGridWindow()->UnsetToolTip();
1277 std::set<SCH_REFERENCE> refs;
1278 std::set<SCH_ITEM*> symbols;
1281 if( aEvent.Selecting() )
1283 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1290 symbols.insert( ref.GetSymbol() );
1297 if( refs.size() > 0 )
1301 wxString symbol_path = refs.begin()->GetFullPath();
1314 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1316 if( refs.size() > 0 )
1317 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1330 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1379 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1386 if( saveIncludeExcudedFromBOM )
1430 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1433 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1438 if( saveDlg.ShowModal() == wxID_CANCEL )
1442 wxFileName file = wxFileName( saveDlg.GetPath() );
1443 wxString defaultPath = fn.GetPathWithSep();
1445 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1447 if( !file.MakeRelativeTo( defaultPath ) )
1449 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1450 "file volume)!" ) );
1484 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1485 _(
"OK" ),
_(
"Cancel" ) )
1495 std::function<bool( wxString* )> textResolver =
1496 [&]( wxString* token ) ->
bool
1501 return schematic.ResolveTextVar( &schematic.CurrentSheet(), token, 0 );
1506 if(
path.IsEmpty() )
1508 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1515 wxFileName outputFile = wxFileName::FileName(
path );
1521 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1526 wxFFile out( outputFile.GetFullPath(),
"wb" );
1528 if( !out.IsOpened() )
1530 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1539 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1546 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1554 EndModal( wxID_CANCEL );
1571 m_job->m_bomFmtPresetName = wxEmptyString;
1576 m_job->m_bomPresetName = wxEmptyString;
1593 m_job->m_fieldsOrdered.clear();
1594 m_job->m_fieldsLabels.clear();
1595 m_job->m_fieldsGroupBy.clear();
1599 if( modelField.show )
1600 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1602 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1604 m_job->m_fieldsLabels.emplace_back( modelField.label );
1606 if( modelField.groupBy )
1607 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1612 if( !selectedVariant.IsEmpty() )
1613 m_job->m_variantNames.push_back( selectedVariant );
1615 EndModal( wxID_OK );
1632 m_grid->CommitPendingChanges(
true );
1648 m_parent->Schematic().RemoveListener(
this );
1651 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1653 if( wxWindow* parent = GetParent() )
1654 wxQueueEvent( parent, evt );
1660 std::vector<BOM_PRESET> ret;
1662 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1664 if( !pair.second.readOnly )
1665 ret.emplace_back( pair.second );
1677 for(
const BOM_PRESET& preset : aPresetList )
1695 wxCommandEvent
dummy;
1738 int default_idx = 0;
1742 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1767 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1769 const BOM_PRESET& preset = aPair.second;
1772 if( !( preset.sortAsc == current.sortAsc
1773 && preset.filterString == current.filterString
1774 && preset.groupSymbols == current.groupSymbols
1775 && preset.excludeDNP == current.excludeDNP
1776 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1787 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1791 std::vector<BOM_FIELD>
A,
B;
1793 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1795 if( field.show || field.groupBy )
1796 A.emplace_back( field );
1801 if( field.show || field.groupBy )
1802 B.emplace_back( field );
1808 if( it != m_bomPresets.end() )
1812 bool do_translate = it->second.readOnly;
1813 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1814 m_cbBomPresets->SetStringSelection(
text );
1818 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1821 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1830 wxString ui_label = aName;
1834 if( presetName == aName )
1836 if( preset.readOnly ==
true )
1837 ui_label = wxGetTranslation( aName );
1862 auto resetSelection =
1871 if(
index == count - 3 )
1877 else if(
index == count - 2 )
1885 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1887 if( dlg.ShowModal() != wxID_OK )
1893 name = dlg.GetValue();
1911 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1912 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1919 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1940 else if(
index == count - 1 )
1943 wxArrayString headers;
1944 std::vector<wxArrayString> items;
1946 headers.Add(
_(
"Presets" ) );
1950 if( !preset.readOnly )
1954 items.emplace_back( item );
1966 if( idx != wxNOT_FOUND )
2016 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
2018 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2039 int col =
m_dataModel->GetFieldNameCol( fieldName );
2043 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2048 std::string fieldNameStr( fieldName.ToUTF8() );
2051 const wxString& label =
m_dataModel->GetColLabelValue( col );
2053 m_grid->SetColLabelValue( col, label );
2068 bool groupBy =
m_dataModel->GetGroupColumn( col );
2092 std::vector<BOM_FMT_PRESET> ret;
2096 if( !preset.readOnly )
2097 ret.emplace_back( preset );
2127 wxCommandEvent
dummy;
2169 int default_idx = 0;
2198 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2200 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2201 && aPair.second.stringDelimiter == current.stringDelimiter
2202 && aPair.second.refDelimiter == current.refDelimiter
2203 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2204 && aPair.second.keepTabs == current.keepTabs
2205 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2212 bool do_translate = it->second.readOnly;
2213 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2232 wxString ui_label = aName;
2236 if( presetName == aName )
2238 if( preset.readOnly )
2239 ui_label = wxGetTranslation( aName );
2264 auto resetSelection =
2273 if(
index == count - 3 )
2279 else if(
index == count - 2 )
2287 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2289 if( dlg.ShowModal() != wxID_OK )
2295 name = dlg.GetValue();
2313 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2314 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2321 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2342 else if(
index == count - 1 )
2345 wxArrayString headers;
2346 std::vector<wxArrayString> items;
2348 headers.Add(
_(
"Presets" ) );
2350 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2352 if( !pair.second.readOnly )
2355 item.Add( pair.first );
2356 items.emplace_back( item );
2368 if( idx != wxNOT_FOUND )
2423 bool modified =
false;
2426 std::vector<BOM_PRESET> presets;
2430 if( !preset.readOnly )
2431 presets.emplace_back( preset );
2447 std::vector<BOM_FMT_PRESET> fmts;
2451 if( !preset.readOnly )
2452 fmts.emplace_back( preset );
2491 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2497 std::set<SCH_SYMBOL*> symbols;
2501 symbols.insert( ref.GetSymbol() );
2506 for(
SCH_FIELD& field : symbol->GetFields() )
2507 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2559 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2562 m_parent->Schematic().GetCurrentVariant() );
2566 std::set<SCH_SYMBOL*> symbols;
2570 symbols.insert( ref.GetSymbol() );
2575 for(
SCH_FIELD& field : symbol->GetFields() )
2576 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2594 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2608 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2616 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2624 std::set<wxString> selectedFullPaths;
2626 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2627 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2629 for(
size_t i = 0; i < topLeft.size(); ++i )
2631 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2634 selectedFullPaths.insert( ref.GetFullPath() );
2638 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2640 for(
int row : selectedRows )
2643 selectedFullPaths.insert( ref.GetFullPath() );
2646 int cursorRow =
m_grid->GetGridCursorRow();
2648 if( cursorRow >= 0 && selectedFullPaths.empty() )
2651 selectedFullPaths.insert( ref.GetFullPath() );
2654 return selectedFullPaths;
2660 if( aFullPaths.empty() )
2663 m_grid->ClearSelection();
2665 bool firstSelection =
true;
2667 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2669 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2673 if( aFullPaths.count( ref.GetFullPath() ) )
2675 m_grid->SelectRow( row,
true );
2677 if( firstSelection )
2679 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2680 firstSelection =
false;
2695 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2722 if( basePath.Path() == instance.m_Path )
2730 subSheets.push_back( sheetPath );
2748 if( !
m_parent->ShowAddVariantDialog() )
2751 wxArrayString ctrlContents;
2754 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2755 ctrlContents.Add( variant );
2760 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2764 if( newSelection != wxNOT_FOUND )
2776 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2778 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2779 10000, wxICON_ERROR );
2785 m_parent->Schematic().DeleteVariant( variantName );
2788 int newSelection = std::max( 0, selection - 1 );
2792 m_parent->SetCurrentVariant( selectedVariant );
2794 if(
m_grid->CommitPendingChanges(
true ) )
2796 m_dataModel->SetCurrentVariant( selectedVariant );
2807 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2816 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2818 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2819 10000, wxICON_ERROR );
2825 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2826 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2828 if( dlg.ShowModal() == wxID_CANCEL )
2831 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2834 if( newVariantName.IsEmpty() )
2836 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2843 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2845 10000, wxICON_ERROR );
2850 if( newVariantName == oldVariantName )
2854 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2856 if( existingName.CmpNoCase( newVariantName ) == 0
2857 && existingName.CmpNoCase( oldVariantName ) != 0 )
2859 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2861 0000, wxICON_ERROR );
2866 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2870 ctrlContents.Remove( oldVariantName );
2871 ctrlContents.Add( newVariantName );
2877 if( newSelection != wxNOT_FOUND )
2881 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2890 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2892 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2893 10000, wxICON_ERROR );
2899 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2900 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2902 if( dlg.ShowModal() == wxID_CANCEL )
2905 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2908 if( newVariantName.IsEmpty() )
2910 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2917 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2919 10000, wxICON_ERROR );
2923 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2927 ctrlContents.Add( newVariantName );
2933 if( newSelection != wxNOT_FOUND )
2937 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2945 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2947 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot edit the default variant description." ), 10000,
2953 wxString currentDesc =
m_parent->Schematic().GetVariantDescription( variantName );
2955 wxDialog dlg(
this, wxID_ANY, wxString::Format(
_(
"Edit Description for '%s'" ), variantName ), wxDefaultPosition,
2956 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
2958 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
2960 wxStaticText* label =
new wxStaticText( &dlg, wxID_ANY,
_(
"Description:" ) );
2961 mainSizer->Add( label, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 10 );
2963 mainSizer->AddSpacer( 3 );
2965 wxTextCtrl* descCtrl =
2966 new wxTextCtrl( &dlg, wxID_ANY, currentDesc, wxDefaultPosition, wxSize( 300, 60 ), wxTE_MULTILINE );
2967 mainSizer->Add( descCtrl, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 10 );
2969 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
2970 btnSizer->AddButton(
new wxButton( &dlg, wxID_OK ) );
2971 btnSizer->AddButton(
new wxButton( &dlg, wxID_CANCEL ) );
2972 btnSizer->Realize();
2973 mainSizer->Add( btnSizer, 0, wxALL | wxALIGN_RIGHT, 5 );
2975 dlg.SetSizer( mainSizer );
2979 if( dlg.ShowModal() == wxID_CANCEL )
2982 wxString newDesc = descCtrl->GetValue().Trim().Trim(
false );
2984 m_parent->Schematic().SetVariantDescription( variantName, newDesc );
2991 wxString currentVariant;
2998 currentVariant =
m_parent->Schematic().GetCurrentVariant();
3000 if( currentVariant != selectedVariant )
3001 m_parent->SetCurrentVariant( selectedVariant );
3004 if( currentVariant != selectedVariant )
3006 m_grid->CommitPendingChanges(
true );
3012 if( !commit.
Empty() )
3014 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
3019 m_dataModel->SetCurrentVariant( selectedVariant );
3038 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_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.
#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.