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 )
248 wxGridCellAttr* attr =
new wxGridCellAttr;
249 attr->SetReadOnly(
true );
252 attr =
new wxGridCellAttr;
253 attr->SetRenderer(
new wxGridCellBoolRenderer() );
255 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
258 attr =
new wxGridCellAttr;
259 attr->SetRenderer(
new wxGridCellBoolRenderer() );
261 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
267 m_filter->SetDescriptiveText(
_(
"Filter" ) );
269 attr =
new wxGridCellAttr;
273 m_grid->UseNativeColHeader(
true );
281 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
289 if( !
m_parent->Schematic().GetCurrentVariant().IsEmpty() )
293 if( toSelect == wxNOT_FOUND )
306 SetTitle(
m_job->GetSettingsDialogTitle() );
328 CallAfter( [
this, cfg]()
358 m_parent->Schematic().AddListener(
this );
363 m_grid->EnableEditing(
false );
382 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
384 if(
m_grid->IsColShown( i ) )
386 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
401 m_grid->PopEventHandler(
true );
411 if( aIsLeftPanelCollapsed )
426 wxGridCellAttr* attr =
new wxGridCellAttr;
427 attr->SetReadOnly(
false );
451 attr->SetAlignment( wxALIGN_RIGHT, wxALIGN_CENTER );
452 attr->SetRenderer(
new wxGridCellNumberRenderer() );
457 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
470 attr->SetEditor(
m_grid->GetDefaultEditor() );
479 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
482 m_grid->AutoSizeColumns(
false );
484 bool sortAscending =
true;
486 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
512 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
522 int maxWidth = defaultDlgSize.x / 3;
524 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
534 m_grid->SetSortingColumn( sortCol, sortAscending );
540 if( !wxDialog::TransferDataToWindow() )
563 for(
const wxString& fieldName :
m_job->m_fieldsOrdered )
566 field.
name = fieldName;
567 field.
show = !fieldName.StartsWith( wxT(
"__" ), &field.
name );
570 if( (
m_job->m_fieldsLabels.size() > i ) && !
m_job->m_fieldsLabels[i].IsEmpty() )
591 fmtPreset.
name =
m_job->m_bomFmtPresetName;
612 if( selection.GetSize() == 1 )
624 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
626 std::vector<SCH_REFERENCE> references =
m_dataModel->GetRowReferences( row );
631 if( ref.GetSymbol() == symbol )
645 for(
int col = 0; col <
m_dataModel->GetNumberCols(); col++ )
651 else if( anyCol == -1 &&
m_dataModel->GetShowColumn( col ) )
655 if( valueCol != -1 &&
m_dataModel->GetShowColumn( valueCol ) )
656 m_grid->GoToCell( row, valueCol );
657 else if( refCol != -1 &&
m_dataModel->GetShowColumn( refCol ) )
658 m_grid->GoToCell( row, refCol );
659 else if( anyCol != -1 )
660 m_grid->GoToCell( row, anyCol );
678 if( !
m_grid->CommitPendingChanges() )
681 if( !wxDialog::TransferDataFromWindow() )
692 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
696 if( !commit.
Empty() )
698 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
703 m_parent->SetCurrentSheet( currentSheet );
712 bool show,
bool groupBy,
bool addedByUser )
722 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser,
m_parent->Schematic().GetCurrentVariant() );
724 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
725 m_grid->ProcessTableMessage( msg );
728 [&]() -> std::pair<int, int>
739 auto addMandatoryField =
740 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
760 auto caseInsensitiveLess = [](
const wxString& a,
const wxString& b )
762 return a.CmpNoCase( b ) < 0;
765 std::map<wxString, std::map<wxString, int>,
decltype( caseInsensitiveLess )> userFieldGroups( caseInsensitiveLess );
773 if( !field.IsMandatory() && !field.IsPrivate() )
774 userFieldGroups[field.GetName()][field.GetName()]++;
778 for(
const auto& [groupKey, exactCounts] : userFieldGroups )
780 wxString canonicalName;
784 canonicalName = tfn->m_Name;
790 for(
const auto& [
name, count] : exactCounts )
792 if( count > bestCount )
795 canonicalName =
name;
806 if( userFieldGroups.count( tfn.m_Name ) == 0 )
814 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
816 if( dlg.ShowModal() != wxID_OK )
819 wxString fieldName = dlg.GetValue();
821 if( fieldName.IsEmpty() )
827 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
829 if( fieldName.CmpNoCase(
m_dataModel->GetColFieldName( i ) ) == 0 )
831 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
854 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory." ),
860 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
866 int col =
m_dataModel->GetFieldNameCol( fieldName );
886 if( selectedRows.empty() )
889 int row = selectedRows[0];
895 DisplayError(
this, wxString::Format(
_(
"The first %d fields are mandatory and names cannot be changed." ),
905 int col =
m_dataModel->GetFieldNameCol( fieldName );
906 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
908 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
910 if( dlg.ShowModal() != wxID_OK )
913 wxString newFieldName = dlg.GetValue();
916 if( newFieldName == fieldName )
920 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
922 wxString confirm_msg = wxString::Format(
_(
"Field name %s already exists." ), newFieldName );
931 if( labelIsAutogenerated )
955#if defined( __WXOSX__ )
956 wxPoint pos = aEvent.GetPosition();
957 wxRect ctrlRect =
m_filter->GetScreenRect();
958 int buttonWidth = ctrlRect.GetHeight();
961 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
962 SetCursor( wxCURSOR_ARROW );
963 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
964 SetCursor( wxCURSOR_ARROW );
966 SetCursor( wxCURSOR_IBEAM );
981 switch( aEvent.GetSelection() )
983 case 0:
setScope( SCOPE::SCOPE_ALL );
break;
984 case 1:
setScope( SCOPE::SCOPE_SHEET );
break;
985 case 2:
setScope( SCOPE::SCOPE_SHEET_RECURSIVE );
break;
1007 menu.Append( 4204,
_(
"Include 'DNP' Symbols" ),
1008 _(
"Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
1009 "symbols are included on export." ),
1011 menu.Check( 4204, !
m_dataModel->GetExcludeDNP() );
1013 menu.Append( 4205,
_(
"Include 'Exclude from BOM' Symbols" ),
1014 _(
"Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
1015 "are never included on export." ),
1017 menu.Check( 4205,
m_dataModel->GetIncludeExcludedFromBOM() );
1019 menu.AppendSeparator();
1021 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1022 _(
"Highlight corresponding item on canvas when it is selected in the table" ),
1026 menu.Append( 4207,
_(
"Select on Cross-probe" ),
1027 _(
"Select corresponding item on canvas when it is selected in the table" ),
1032 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1034 if( menu_id == 0 || menu_id == 4204 )
1042 else if( menu_id == 1 || menu_id == 4205 )
1050 else if( menu_id == 3 || menu_id == 4206 )
1057 else if( menu_id == 4 || menu_id == 4207 )
1069 int sortCol = aEvent.GetCol();
1070 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1082 if(
m_grid->IsSortingBy( sortCol ) )
1085 ascending = !
m_grid->IsSortOrderAscending();
1103 int origPos = aEvent.GetCol();
1108 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1110 if(
m_grid->IsColShown( i ) )
1112 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1120 int newPos =
m_grid->GetColPos( origPos );
1123 if( newPos < origPos )
1164 int row = aEvent.GetRow();
1166 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1168 switch( aEvent.GetCol() )
1174 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1179 m_grid->SetColLabelValue( dataCol, label );
1197 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1209 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1211 if(
m_dataModel->ColIsQuantity( dataCol ) && value )
1213 DisplayError(
this,
_(
"The Quantity column cannot be grouped by." ) );
1220 if(
m_dataModel->ColIsItemNumber( dataCol ) && value )
1222 DisplayError(
this,
_(
"The Item Number column cannot be grouped by." ) );
1271 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
1273 m_grid->ClearSelection();
1276 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
1289 wxPoint pos = aEvent.GetPosition();
1291 m_grid->CalcUnscrolledPosition( pos.x, pos.y, &ux, &uy );
1292 int row =
m_grid->YToRow( uy );
1293 int col =
m_grid->XToCol( ux );
1296 if( row == wxNOT_FOUND || col == wxNOT_FOUND )
1298 m_grid->GetGridWindow()->UnsetToolTip();
1302 wxString rawValue =
m_dataModel->GetValue( row, col );
1304 if( rawValue.Contains( wxT(
"${" ) ) )
1306 m_grid->GetGridWindow()->SetToolTip( rawValue );
1310 m_grid->GetGridWindow()->UnsetToolTip();
1325 std::set<SCH_REFERENCE> refs;
1326 std::set<SCH_ITEM*> symbols;
1329 if( aEvent.Selecting() )
1331 for(
int i = aEvent.GetTopRow(); i <= aEvent.GetBottomRow(); i++ )
1338 symbols.insert( ref.GetSymbol() );
1345 if( refs.size() > 0 )
1349 wxString symbol_path = refs.begin()->GetFullPath();
1362 std::vector<SCH_ITEM*> items( symbols.begin(), symbols.end() );
1364 if( refs.size() > 0 )
1365 selTool->
SyncSelection( refs.begin()->GetSheetPath(),
nullptr, items );
1378 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
1427 bool saveIncludeExcudedFromBOM =
m_dataModel->GetIncludeExcludedFromBOM();
1434 if( saveIncludeExcudedFromBOM )
1478 wxFileName fn(
Prj().AbsolutePath(
m_parent->Schematic().GetFileName() ) );
1481 wxFileDialog saveDlg(
this,
_(
"Bill of Materials Output File" ),
path, fn.GetFullName(),
1486 if( saveDlg.ShowModal() == wxID_CANCEL )
1490 wxFileName file = wxFileName( saveDlg.GetPath() );
1491 wxString defaultPath = fn.GetPathWithSep();
1493 if(
IsOK(
this, wxString::Format(
_(
"Do you want to use a path relative to\n'%s'?" ), defaultPath ) ) )
1495 if( !file.MakeRelativeTo( defaultPath ) )
1497 DisplayErrorMessage(
this,
_(
"Cannot make path relative (target volume different from schematic "
1498 "file volume)!" ) );
1532 _(
"Changes have not yet been saved. Export unsaved data?" ),
"",
1533 _(
"OK" ),
_(
"Cancel" ) )
1543 std::function<bool( wxString* )> textResolver =
1544 [&]( wxString* token ) ->
bool
1549 return schematic.ResolveTextVar( &schematic.CurrentSheet(), token, 0 );
1554 if(
path.IsEmpty() )
1556 DisplayError(
this,
_(
"No output file specified in Export tab." ) );
1563 wxFileName outputFile = wxFileName::FileName(
path );
1569 msg.Printf(
_(
"Could not open/create path '%s'." ), outputFile.GetPath() );
1574 wxFFile out( outputFile.GetFullPath(),
"wb" );
1576 if( !out.IsOpened() )
1578 msg.Printf(
_(
"Could not create BOM output '%s'." ), outputFile.GetFullPath() );
1587 msg.Printf(
_(
"Could not write BOM output '%s'." ), outputFile.GetFullPath() );
1594 msg.Printf(
_(
"Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
1602 EndModal( wxID_CANCEL );
1619 m_job->m_bomFmtPresetName = wxEmptyString;
1624 m_job->m_bomPresetName = wxEmptyString;
1641 m_job->m_fieldsOrdered.clear();
1642 m_job->m_fieldsLabels.clear();
1643 m_job->m_fieldsGroupBy.clear();
1647 if( modelField.show )
1648 m_job->m_fieldsOrdered.emplace_back( modelField.name );
1650 m_job->m_fieldsOrdered.emplace_back( wxT(
"__" ) + modelField.name );
1652 m_job->m_fieldsLabels.emplace_back( modelField.label );
1654 if( modelField.groupBy )
1655 m_job->m_fieldsGroupBy.emplace_back( modelField.name );
1660 if( !selectedVariant.IsEmpty() )
1661 m_job->m_variantNames.push_back( selectedVariant );
1663 EndModal( wxID_OK );
1680 m_grid->CommitPendingChanges(
true );
1696 m_parent->Schematic().RemoveListener(
this );
1699 wxCommandEvent* evt =
new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxID_ANY );
1701 if( wxWindow* parent = GetParent() )
1702 wxQueueEvent( parent, evt );
1708 std::vector<BOM_PRESET> ret;
1710 for(
const std::pair<const wxString, BOM_PRESET>& pair :
m_bomPresets )
1712 if( !pair.second.readOnly )
1713 ret.emplace_back( pair.second );
1725 for(
const BOM_PRESET& preset : aPresetList )
1743 wxCommandEvent
dummy;
1786 int default_idx = 0;
1790 m_cbBomPresets->Append( wxGetTranslation( presetName ), (
void*) &preset );
1815 [&](
const std::pair<const wxString, BOM_PRESET>& aPair )
1817 const BOM_PRESET& preset = aPair.second;
1820 if( !( preset.sortAsc == current.sortAsc
1821 && preset.filterString == current.filterString
1822 && preset.groupSymbols == current.groupSymbols
1823 && preset.excludeDNP == current.excludeDNP
1824 && preset.includeExcludedFromBOM == current.includeExcludedFromBOM ) )
1835 if( preset.sortField != wxGetTranslation( current.
sortField ) )
1839 std::vector<BOM_FIELD>
A,
B;
1841 for(
const BOM_FIELD& field : preset.fieldsOrdered )
1843 if( field.show || field.groupBy )
1844 A.emplace_back( field );
1849 if( field.show || field.groupBy )
1850 B.emplace_back( field );
1856 if( it != m_bomPresets.end() )
1860 bool do_translate = it->second.readOnly;
1861 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
1862 m_cbBomPresets->SetStringSelection(
text );
1866 m_cbBomPresets->SetSelection( m_cbBomPresets->GetCount() - 3 );
1869 m_currentBomPreset =
static_cast<BOM_PRESET*
>( m_cbBomPresets->GetClientData( m_cbBomPresets->GetSelection() ) );
1878 wxString ui_label = aName;
1882 if( presetName == aName )
1884 if( preset.readOnly ==
true )
1885 ui_label = wxGetTranslation( aName );
1910 auto resetSelection =
1919 if(
index == count - 3 )
1925 else if(
index == count - 2 )
1933 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
1935 if( dlg.ShowModal() != wxID_OK )
1941 name = dlg.GetValue();
1959 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
1960 _(
"Error" ), wxOK | wxICON_ERROR,
this );
1967 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
1988 else if(
index == count - 1 )
1991 wxArrayString headers;
1992 std::vector<wxArrayString> items;
1994 headers.Add(
_(
"Presets" ) );
1998 if( !preset.readOnly )
2002 items.emplace_back( item );
2014 if( idx != wxNOT_FOUND )
2064 for(
int i = 0; i <
m_dataModel->GetColsCount(); i++ )
2066 const wxString& fieldName(
m_dataModel->GetColFieldName( i ) );
2087 int col =
m_dataModel->GetFieldNameCol( fieldName );
2091 wxASSERT_MSG(
true,
"Fields control has a field not found in the data model." );
2096 std::string fieldNameStr( fieldName.ToUTF8() );
2099 const wxString& label =
m_dataModel->GetColLabelValue( col );
2101 m_grid->SetColLabelValue( col, label );
2116 bool groupBy =
m_dataModel->GetGroupColumn( col );
2140 std::vector<BOM_FMT_PRESET> ret;
2144 if( !preset.readOnly )
2145 ret.emplace_back( preset );
2175 wxCommandEvent
dummy;
2217 int default_idx = 0;
2246 [&](
const std::pair<const wxString, BOM_FMT_PRESET>& aPair )
2248 return ( aPair.second.fieldDelimiter == current.fieldDelimiter
2249 && aPair.second.stringDelimiter == current.stringDelimiter
2250 && aPair.second.refDelimiter == current.refDelimiter
2251 && aPair.second.refRangeDelimiter == current.refRangeDelimiter
2252 && aPair.second.keepTabs == current.keepTabs
2253 && aPair.second.keepLineBreaks == current.keepLineBreaks );
2260 bool do_translate = it->second.readOnly;
2261 wxString
text = do_translate ? wxGetTranslation( it->first ) : it->first;
2280 wxString ui_label = aName;
2284 if( presetName == aName )
2286 if( preset.readOnly )
2287 ui_label = wxGetTranslation( aName );
2312 auto resetSelection =
2321 if(
index == count - 3 )
2327 else if(
index == count - 2 )
2335 wxTextEntryDialog dlg(
this,
_(
"BOM preset name:" ),
_(
"Save BOM Preset" ),
name );
2337 if( dlg.ShowModal() != wxID_OK )
2343 name = dlg.GetValue();
2361 wxMessageBox(
_(
"Default presets cannot be modified.\nPlease use a different name." ),
2362 _(
"Error" ), wxOK | wxICON_ERROR,
this );
2369 if( !
IsOK(
this,
_(
"Overwrite existing preset?" ) ) )
2390 else if(
index == count - 1 )
2393 wxArrayString headers;
2394 std::vector<wxArrayString> items;
2396 headers.Add(
_(
"Presets" ) );
2398 for( std::pair<const wxString, BOM_FMT_PRESET>& pair :
m_bomFmtPresets )
2400 if( !pair.second.readOnly )
2403 item.Add( pair.first );
2404 items.emplace_back( item );
2416 if( idx != wxNOT_FOUND )
2471 bool modified =
false;
2474 std::vector<BOM_PRESET> presets;
2478 if( !preset.readOnly )
2479 presets.emplace_back( preset );
2495 std::vector<BOM_FMT_PRESET> fmts;
2499 if( !preset.readOnly )
2500 fmts.emplace_back( preset );
2539 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2545 std::set<SCH_SYMBOL*> symbols;
2549 symbols.insert( ref.GetSymbol() );
2554 for(
SCH_FIELD& field : symbol->GetFields() )
2555 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2607 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2610 m_parent->Schematic().GetCurrentVariant() );
2614 std::set<SCH_SYMBOL*> symbols;
2618 symbols.insert( ref.GetSymbol() );
2623 for(
SCH_FIELD& field : symbol->GetFields() )
2624 AddField( field.GetCanonicalName(), field.GetName(),
true,
false,
true );
2642 if(
m_dataModel->GetScope() != FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE::SCOPE_ALL )
2656 m_grid->Connect( wxEVT_GRID_RANGE_SELECTED,
2664 m_grid->Disconnect( wxEVT_GRID_RANGE_SELECTED,
2672 std::set<wxString> selectedFullPaths;
2674 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
2675 wxGridCellCoordsArray bottomRight =
m_grid->GetSelectionBlockBottomRight();
2677 for(
size_t i = 0; i < topLeft.size(); ++i )
2679 for(
int row = topLeft[i].GetRow(); row <= bottomRight[i].GetRow(); ++row )
2682 selectedFullPaths.insert( ref.GetFullPath() );
2686 wxArrayInt selectedRows =
m_grid->GetSelectedRows();
2688 for(
int row : selectedRows )
2691 selectedFullPaths.insert( ref.GetFullPath() );
2694 int cursorRow =
m_grid->GetGridCursorRow();
2696 if( cursorRow >= 0 && selectedFullPaths.empty() )
2699 selectedFullPaths.insert( ref.GetFullPath() );
2702 return selectedFullPaths;
2708 if( aFullPaths.empty() )
2711 m_grid->ClearSelection();
2713 bool firstSelection =
true;
2715 for(
int row = 0; row <
m_dataModel->GetNumberRows(); ++row )
2717 std::vector<SCH_REFERENCE> refs =
m_dataModel->GetRowReferences( row );
2721 if( aFullPaths.count( ref.GetFullPath() ) )
2723 m_grid->SelectRow( row,
true );
2725 if( firstSelection )
2727 m_grid->SetGridCursor( row,
m_grid->GetGridCursorCol() );
2728 firstSelection =
false;
2743 for(
size_t i = 0; i < aCachedRefs.
GetCount(); i++ )
2770 if( basePath.Path() == instance.m_Path )
2778 subSheets.push_back( sheetPath );
2796 if( !
m_parent->ShowAddVariantDialog() )
2799 wxArrayString ctrlContents;
2802 for(
const wxString& variant :
m_parent->Schematic().GetVariantNames() )
2803 ctrlContents.Add( variant );
2808 wxString currentVariant =
m_parent->Schematic().GetCurrentVariant();
2812 if( newSelection != wxNOT_FOUND )
2824 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2826 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot delete the default variant." ),
2827 10000, wxICON_ERROR );
2833 m_parent->Schematic().DeleteVariant( variantName );
2836 int newSelection = std::max( 0, selection - 1 );
2840 m_parent->SetCurrentVariant( selectedVariant );
2842 if(
m_grid->CommitPendingChanges(
true ) )
2844 m_dataModel->SetCurrentVariant( selectedVariant );
2855 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2864 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2866 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot rename the default variant." ),
2867 10000, wxICON_ERROR );
2873 wxTextEntryDialog dlg(
this,
_(
"Enter new variant name:" ),
_(
"Rename Design Variant" ),
2874 oldVariantName, wxOK | wxCANCEL | wxCENTER );
2876 if( dlg.ShowModal() == wxID_CANCEL )
2879 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2882 if( newVariantName.IsEmpty() )
2884 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2891 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"'%s' is a reserved variant name." ),
2893 10000, wxICON_ERROR );
2898 if( newVariantName == oldVariantName )
2902 for(
const wxString& existingName :
m_parent->Schematic().GetVariantNames() )
2904 if( existingName.CmpNoCase( newVariantName ) == 0
2905 && existingName.CmpNoCase( oldVariantName ) != 0 )
2907 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2909 0000, wxICON_ERROR );
2914 m_parent->Schematic().RenameVariant( oldVariantName, newVariantName );
2918 ctrlContents.Remove( oldVariantName );
2919 ctrlContents.Add( newVariantName );
2925 if( newSelection != wxNOT_FOUND )
2929 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2938 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2940 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot copy the default variant." ),
2941 10000, wxICON_ERROR );
2947 wxTextEntryDialog dlg(
this,
_(
"Enter name for the copied variant:" ),
_(
"Copy Design Variant" ),
2948 sourceVariantName + wxS(
"_copy" ), wxOK | wxCANCEL | wxCENTER );
2950 if( dlg.ShowModal() == wxID_CANCEL )
2953 wxString newVariantName = dlg.GetValue().Trim().Trim(
false );
2956 if( newVariantName.IsEmpty() )
2958 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Variant name cannot be empty." ), 10000, wxICON_ERROR );
2965 m_parent->GetInfoBar()->ShowMessageFor( wxString::Format(
_(
"Variant '%s' already exists." ),
2967 10000, wxICON_ERROR );
2971 m_parent->Schematic().CopyVariant( sourceVariantName, newVariantName );
2975 ctrlContents.Add( newVariantName );
2981 if( newSelection != wxNOT_FOUND )
2985 m_parent->UpdateVariantSelectionCtrl(
m_parent->Schematic().GetVariantNamesForUI() );
2993 if( ( selection == wxNOT_FOUND ) || ( selection == 0 ) )
2995 m_parent->GetInfoBar()->ShowMessageFor(
_(
"Cannot edit the default variant description." ), 10000,
3001 wxString currentDesc =
m_parent->Schematic().GetVariantDescription( variantName );
3003 wxDialog dlg(
this, wxID_ANY, wxString::Format(
_(
"Edit Description for '%s'" ), variantName ), wxDefaultPosition,
3004 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
3006 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
3008 wxStaticText* label =
new wxStaticText( &dlg, wxID_ANY,
_(
"Description:" ) );
3009 mainSizer->Add( label, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 10 );
3011 mainSizer->AddSpacer( 3 );
3013 wxTextCtrl* descCtrl =
3014 new wxTextCtrl( &dlg, wxID_ANY, currentDesc, wxDefaultPosition, wxSize( 300, 60 ), wxTE_MULTILINE );
3015 mainSizer->Add( descCtrl, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 10 );
3017 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
3018 btnSizer->AddButton(
new wxButton( &dlg, wxID_OK ) );
3019 btnSizer->AddButton(
new wxButton( &dlg, wxID_CANCEL ) );
3020 btnSizer->Realize();
3021 mainSizer->Add( btnSizer, 0, wxALL | wxALIGN_RIGHT, 5 );
3023 dlg.SetSizer( mainSizer );
3027 if( dlg.ShowModal() == wxID_CANCEL )
3030 wxString newDesc = descCtrl->GetValue().Trim().Trim(
false );
3032 m_parent->Schematic().SetVariantDescription( variantName, newDesc );
3039 wxString currentVariant;
3046 currentVariant =
m_parent->Schematic().GetCurrentVariant();
3048 if( currentVariant != selectedVariant )
3049 m_parent->SetCurrentVariant( selectedVariant );
3052 if( currentVariant != selectedVariant )
3054 m_grid->CommitPendingChanges(
true );
3060 if( !commit.
Empty() )
3062 commit.
Push( wxS(
"Symbol Fields Table Edit" ) );
3067 m_dataModel->SetCurrentVariant( selectedVariant );
3086 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 ExcludeFromControlUndoRedo(wxWindow *aWindow)
Opt a control out of the dialog's generic Ctrl+Z/Ctrl+Y undo/redo.
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.