28#include <wx/textdlg.h>
29#include <wx/wupdlock.h>
70 const int col = aEvent.GetCol();
79 wxString::Format(
_(
"Reset '%s' to 1:1" ),
m_panel->GetColumnMapName( col ) ) );
81 wxMenu* copyMenu =
new wxMenu;
89 copyMenu->Append( copyId,
m_panel->GetColumnMapName( other ) );
94 if( copyMenu->GetMenuItemCount() > 0 )
95 menu.Append( wxID_ANY,
_(
"Copy From..." ), copyMenu );
99 menu.AppendSeparator();
107 const int id = aEvent.GetId();
138 m_grid->SetUseNativeColLabels();
141 if(
m_grid->GetNumberCols() > 0 )
145 m_grid->SetColLabelValue( 0,
_(
"Unit" ) );
146 m_grid->SetColLabelValue( 1,
_(
"Symbol Pin" ) );
147 m_grid->SetColLabelValue( 2,
_(
"Name" ) );
162 m_grid->PopEventHandler();
177 std::set<wxString> seen;
181 if( seen.insert( logical.number ).second )
199 if( !
m_grid->CommitPendingChanges() )
211 return m_grid->CommitPendingChanges();
229 wxWindowUpdateLocker lock(
m_grid );
231 const std::vector<PIN_MAP>& maps =
m_pinMaps.GetAll();
232 const int wantCols =
FIXED_COLS + (int) maps.size();
234 if(
m_grid->GetNumberCols() > wantCols )
235 m_grid->DeleteCols( wantCols,
m_grid->GetNumberCols() - wantCols );
236 else if(
m_grid->GetNumberCols() < wantCols )
237 m_grid->AppendCols( wantCols -
m_grid->GetNumberCols() );
239 for(
size_t ii = 0; ii < maps.size(); ++ii )
242 if(
m_grid->GetNumberRows() > 0 )
248 m_grid->SetCellValue( 0, 0,
_(
"Footprint" ) );
249 m_grid->SetReadOnly( 0, 0 );
253 for(
size_t col = 0; col < maps.size(); ++col )
259 if( assoc.m_MapName == maps[col].GetName() )
261 footprint = assoc.m_FootprintLibId.GetUniStringLibId();
286 const size_t row = std::distance(
m_pinNumbers.begin(), it );
288 if( pinNames[row].IsEmpty() && logical.pin )
290 pinNames[row] = logical.pin->GetName();
291 pinUnits[row] = logical.pin->GetUnit();
298 const int gridRow = (int) row + 1;
299 const wxString unit =
300 pinUnits[row] > 0 ? wxString::Format( wxT(
"%d" ), pinUnits[row] ) : wxString( wxT(
"-" ) );
302 m_grid->SetCellValue( gridRow, 0, unit );
304 m_grid->SetCellValue( gridRow, 2, pinNames[row] );
306 m_grid->SetReadOnly( gridRow, 0 );
307 m_grid->SetReadOnly( gridRow, 1 );
308 m_grid->SetReadOnly( gridRow, 2 );
310 for(
size_t col = 0; col < maps.size(); ++col )
329 for(
int row = 1; row <
m_grid->GetNumberRows(); ++row )
339 if( aRow < 1 || aRow >=
m_grid->GetNumberRows() || aCol < FIXED_COLS || aCol >=
m_grid->GetNumberCols() )
342 const wxString
pad =
m_grid->GetCellValue( aRow, aCol );
348 std::vector<wxString> expanded;
353 const wxColour defaultColour =
m_grid->GetDefaultCellBackgroundColour();
354 wxColour background = defaultColour;
358 background.Set( 255, 190, 190 );
360 else if( !expanded.empty() )
363 const std::vector<PIN_MAP>& maps =
m_pinMaps.GetAll();
365 if(
index < maps.size() )
367 std::set<wxString> pads;
371 if( assoc.m_MapName != maps[
index].GetName() )
374 const std::set<wxString>& fpPads =
padNumbersFor( assoc.m_FootprintLibId.GetUniStringLibId() );
375 pads.insert( fpPads.begin(), fpPads.end() );
379 && std::any_of( expanded.begin(), expanded.end(),
380 [&](
const wxString& p )
382 return !pads.count( p );
385 background.Set( 250, 230, 150 );
391 background = background.ChangeLightness( 50 );
393 m_grid->SetCellBackgroundColour( aRow, aCol, background );
399 if( aEvent.GetRow() == 0 && aEvent.GetCol() >=
FIXED_COLS )
424 const std::vector<PIN_MAP>& maps =
m_pinMaps.GetAll();
426 if(
index >= maps.size() )
427 return wxEmptyString;
429 return maps[
index].GetName();
435 if( !
m_grid->CommitPendingChanges() || aCol < FIXED_COLS || aCol >=
m_grid->GetNumberCols() )
438 for(
int row = 1; row <
m_grid->GetNumberRows(); ++row )
440 m_grid->SetCellValue( row, aCol,
m_grid->GetCellValue( row, 1 ) );
450 if( !
m_grid->CommitPendingChanges() )
453 if( aSrcCol < FIXED_COLS || aSrcCol >=
m_grid->GetNumberCols() )
456 if( aDstCol < FIXED_COLS || aDstCol >=
m_grid->GetNumberCols() )
459 for(
int row = 1; row <
m_grid->GetNumberRows(); ++row )
461 m_grid->SetCellValue( row, aDstCol,
m_grid->GetCellValue( row, aSrcCol ) );
471 if( !
m_grid->CommitPendingChanges() || aCol < FIXED_COLS || aCol >=
m_grid->GetNumberCols() )
476 if( oldName.IsEmpty() )
479 wxTextEntryDialog dlg(
this,
_(
"Map name:" ),
_(
"Rename Map" ), oldName );
481 if( dlg.ShowModal() != wxID_OK )
484 const wxString newName = dlg.GetValue().Trim().Trim(
false );
486 if( newName.IsEmpty() || newName == oldName )
491 wxMessageBox( wxString::Format(
_(
"A pin map named '%s' already exists." ), newName ),
_(
"Rename Map" ),
492 wxOK | wxICON_ERROR,
this );
499 map->SetName( newName );
503 if( assoc.m_MapName == oldName )
504 assoc.m_MapName = newName;
515 if( mapName.IsEmpty() )
518 auto currentFootprint = [&]() -> wxString
522 if( a.m_MapName == mapName )
523 return a.m_FootprintLibId.GetUniStringLibId();
526 return wxEmptyString;
529 wxString fpid = aFootprintId;
530 fpid.Trim().Trim(
false );
534 if( !fpid.IsEmpty() && fpId.
Parse( fpid ) >= 0 )
536 wxMessageBox(
_(
"Invalid footprint identifier." ),
_(
"Assign Footprint" ), wxOK | wxICON_ERROR,
this );
537 m_grid->SetCellValue( 0, aCol, currentFootprint() );
543 if( a.m_MapName != mapName && a.m_FootprintLibId == fpId && !fpid.IsEmpty() )
545 wxMessageBox(
_(
"That footprint is already assigned to another pin map." ),
_(
"Assign Footprint" ),
546 wxOK | wxICON_INFORMATION,
this );
547 m_grid->SetCellValue( 0, aCol, currentFootprint() );
555 return a.m_MapName == mapName;
559 if( !fpid.IsEmpty() )
570 m_grid->SetCellValue( 0, aCol, wxEmptyString );
573 for(
int row = 1; row <
m_grid->GetNumberRows(); ++row )
582 if(
m_grid->GetNumberCols() == 0 )
586 m_grid->AutoSizeColumn( col,
false );
591 fixedWidth +=
m_grid->GetColSize( col );
598 const int remaining = std::max(
m_grid->GetClientSize().GetWidth() - fixedWidth, padCols * 80 );
601 m_grid->SetColSize( col, remaining / padCols );
609 std::vector<wxString> names;
612 names.push_back( map.GetName() );
616 for(
size_t col = 0; col < names.size(); ++col )
641 wxString candidate = wxString::Format( wxT(
"map%d" ), suffix++ );
658 if( aFootprintId.IsEmpty() )
665 typedef void ( *PAD_NUMBERS_FN_PTR )(
const wxString&,
PROJECT*, std::set<wxString>& );
668 fetch( aFootprintId, &holder->Prj(), pads );
678 if( !
m_grid->CommitPendingChanges() )
689 if( !
m_grid->CommitPendingChanges() )
692 const std::vector<PIN_MAP>& maps =
m_pinMaps.GetAll();
697 int col =
m_grid->GetGridCursorCol();
701 if( maps.size() > 1 )
703 wxMessageBox(
_(
"Click a pin map column to choose which map to remove." ),
_(
"Remove Pin Map" ),
704 wxOK | wxICON_INFORMATION,
this );
713 if(
index >= maps.size() )
716 const wxString mapName = maps[
index].GetName();
721 return a.m_MapName == mapName;
725 && !
IsOK(
this, wxString::Format(
_(
"Remove pin map '%s' and its footprint association?" ), mapName ) ) )
737 return a.m_MapName == mapName;
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
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.
A mix in class which holds the location of a wxWindow's KIWAY.
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
wxString GetUniStringLibId() const
Define a library symbol object.
void SetAssociatedFootprints(std::vector< ASSOCIATED_FOOTPRINT > aList)
void SetPinMaps(const PIN_MAP_SET &aPinMaps)
STD_BITMAP_BUTTON * m_addMapButton
STD_BITMAP_BUTTON * m_removeMapButton
PANEL_SYMBOL_PIN_MAP_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
Composed widget that edits a symbol's named pin maps and the footprint each is bound to.
static constexpr int FIXED_COLS
Number of fixed leading columns (unit, pin number, pin name).
void rebuildGrid()
Rebuild the whole grid from the working model.
void ValidateCell(int aRow, int aCol)
Re-evaluate the colour of pad cell (aRow, aCol) from its current contents.
std::vector< ASSOCIATED_FOOTPRINT > m_associations
void RenameColumn(int aCol)
Prompt for a new name for column aCol's map and update every reference to it.
void OnAddMap(wxCommandEvent &aEvent) override
const std::set< wxString > & padNumbersFor(const wxString &aFootprintId)
void onLabelDClick(wxGridEvent &aEvent)
Double-clicking a map column's header opens its rename dialog.
PANEL_SYMBOL_PIN_MAP(wxWindow *aParent)
void harvestGrid()
Read every pad cell back into the working pin maps.
void CopyColumn(int aSrcCol, int aDstCol)
Copy every pad value from column aSrcCol into column aDstCol.
void onCellChanged(wxGridEvent &aEvent)
std::vector< wxString > m_pinNumbers
void applyColumnFootprint(int aCol, const wxString &aFootprintId)
Bind (or clear, when empty) the footprint entered in column aCol's footprint cell.
void ApplyToSymbol(LIB_SYMBOL *aSymbol)
Write the edited pin maps and associations into aSymbol.
wxString makeUniqueMapName() const
bool TransferDataToWindow() override
void ResetColumnToIdentity(int aCol)
Set every cell in pad column aCol back to its row's symbol pin number (1:1).
void SetSymbol(LIB_SYMBOL *aSymbol)
Load the editable state from aSymbol.
void OnSizeGrid(wxSizeEvent &aEvent) override
~PANEL_SYMBOL_PIN_MAP() override
std::map< wxString, std::set< wxString > > m_footprintPads
bool CommitPendingChanges()
Commit any in-progress grid cell edit;.
bool TransferDataFromWindow() override
void validateAllCells()
Re-evaluate the colour of every pad cell.
void OnRemoveMap(wxCommandEvent &aEvent) override
std::unique_ptr< PIN_MAP_GRID_TRICKS > m_gridTricks
void adjustGridColumns()
Resize the pad columns to fill the available width.
wxString GetColumnMapName(int aCol) const
std::map< int, int > m_copyFromCols
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
PANEL_SYMBOL_PIN_MAP * m_panel
void doPopupSelection(wxCommandEvent &aEvent) override
PIN_MAP_GRID_TRICKS(WX_GRID *aGrid, PANEL_SYMBOL_PIN_MAP *aPanel)
A symbol-owned ordered set of named pin maps.
void AddOrReplace(PIN_MAP aMap)
Insert aMap, replacing any existing entry with the same name.
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
Container for project specific data.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
This file is part of the common library.
@ GRIDTRICKS_FIRST_CLIENT_ID
@ KIFACE_FOOTPRINT_PAD_NUMBERS
Function pointer type: void (*)( const wxString& aFootprint, PROJECT* aProject, std::set<wxString>& a...
@ PIN_MAP_MENU_RESET_COLUMN
@ PIN_MAP_MENU_COPY_FROM_FIRST
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
Implement a participant in the KIWAY alchemy.
Logical pins: Return expanded logical pins based on stacked-pin notation.