22#include <wx/filedlg.h>
23#include <wx/wfstream.h>
25#include <wx/tokenzr.h>
79 default: wxFAIL;
return wxEmptyString;
130 return wxEmptyString;
154 if( !parent->IsMultiUnit() )
166 if( !parent->IsMultiBodyStyle() )
176 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
177 return wxEmptyString;
200 if(
PinTypeNames().Index( aValue,
false ) != wxNOT_FOUND )
244 if( !parent->IsMultiUnit() )
269 if( !parent->IsMultiBodyStyle() )
292 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
301 wxGridCellCoordsArray topLeft = aGrid->GetSelectionBlockTopLeft();
302 wxGridCellCoordsArray botRight = aGrid->GetSelectionBlockBottomRight();
304 wxArrayInt cols = aGrid->GetSelectedCols();
305 wxArrayInt rows = aGrid->GetSelectedRows();
307 if( topLeft.Count() && botRight.Count() )
309 *aRowStart = topLeft[0].GetRow();
310 *aRowCount = botRight[0].GetRow() - *aRowStart + 1;
312 else if( cols.Count() )
315 *aRowCount = aGrid->GetNumberRows();
317 else if( rows.Count() )
319 *aRowStart = rows[0];
320 *aRowCount = rows.Count();
324 *aRowStart = aGrid->GetGridCursorRow();
325 *aRowCount = *aRowStart >= 0 ? 1 : 0;
336 const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
346 m_eval = std::make_unique<NUMERIC_EVALUATOR>(
m_frame->GetUserUnits() );
359 GetView()->ForceRefresh();
383 wxGrid*
grid = GetView();
385 if(
grid->GetGridCursorRow() == aRow &&
grid->GetGridCursorCol() == aCol &&
grid->IsCellEditControlShown() )
421 if( fieldValue.length() )
422 fieldValue += wxT(
", " );
428 if( !fieldValue.Length() )
430 else if( val != fieldValue )
438 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
443 wxString value = aValue;
454 if(
m_eval->Process( value ) )
466 std::vector<SCH_PIN*> pins =
m_rows[ aRow ];
472 wxStringTokenizer tokenizer( value,
"," );
475 while( tokenizer.HasMoreTokens() )
477 wxString pinName = tokenizer.GetNextToken();
480 pinName.Trim(
true ).Trim(
false );
482 if( i < pins.size() )
485 pins.at( i )->SetNumber( pinName );
507 pos.
y -=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
511 pos.
x +=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
517 pins.push_back( newPin );
524 while( pins.size() > i )
545 static int findRow(
const std::vector<std::vector<SCH_PIN*>>& aRowSet,
const wxString& aName )
547 for(
size_t i = 0; i < aRowSet.size(); ++i )
549 if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
556 static bool compare(
const std::vector<SCH_PIN*>& lhs,
const std::vector<SCH_PIN*>& rhs,
559 wxString lhStr =
GetValue( lhs, sortCol, parentFrame );
560 wxString rhStr =
GetValue( rhs, sortCol, parentFrame );
566 lhStr =
GetValue( lhs, sortCol, parentFrame );
567 rhStr =
GetValue( rhs, sortCol, parentFrame );
575 [ ascending ](
const auto a,
const auto b )
612 void RebuildRows(
const std::vector<SCH_PIN*>& aPins,
bool groupByName,
bool groupBySelection )
615 std::vector<SCH_PIN*> clear_flags;
617 clear_flags.reserve( aPins.size() );
621 if( groupBySelection )
624 pin->ClearTempFlags();
626 int firstSelectedRow;
627 int selectedRowCount;
631 for(
int ii = 0; ii < selectedRowCount; ++ii )
636 clear_flags.push_back(
pin );
643 grid->CommitPendingChanges(
true );
645 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
646 GetView()->ProcessTableMessage( msg );
651 if( groupBySelection )
652 m_rows.emplace_back( std::vector<SCH_PIN*>() );
654 std::set<wxString> selectedNumbers;
657 selectedNumbers.insert(
pin->GetNumber() );
659 const auto pinIsInEditorSelection =
664 if( selectedNumbers.count(
pin->GetNumber() ) == 0 )
672 if( selectedPin->GetNumber() ==
pin->GetNumber()
673 && selectedPin->GetName() ==
pin->GetName()
674 && selectedPin->GetUnit() ==
pin->GetUnit()
675 && selectedPin->GetBodyStyle() ==
pin->GetBodyStyle() )
687 const bool includedByBodyStyle =
691 if( includedByUnit && includedByBodyStyle && includedBySelection )
697 else if( groupBySelection && (
pin->GetFlags() &
CANDIDATE ) )
702 m_rows.emplace_back( std::vector<SCH_PIN*>() );
703 rowIndex =
m_rows.size() - 1;
711 bool ascending =
true;
713 if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
715 sortCol = GetView()->GetSortingColumn();
716 ascending = GetView()->IsSortOrderAscending();
719 for( std::vector<SCH_PIN*>& row :
m_rows )
722 if( !groupBySelection )
727 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
728 GetView()->ProcessTableMessage( msg );
730 if( groupBySelection )
731 GetView()->SelectRow( 0 );
741 [ aSortCol, ascending,
this ](
const std::vector<SCH_PIN*>& lhs,
742 const std::vector<SCH_PIN*>& rhs ) ->
bool
744 return compare( lhs, rhs, aSortCol, ascending, m_frame );
750 std::sort( aRow.begin(), aRow.end(),
753 return PIN_NUMBERS::Compare( lhs->GetNumber(), rhs->GetNumber() ) < 0;
759 std::vector<SCH_PIN*> row;
760 row.push_back( aPin );
765 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
766 GetView()->ProcessTableMessage( msg );
772 std::vector<SCH_PIN*> removedRow =
m_rows[ aRow ];
778 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
779 GetView()->ProcessTableMessage( msg );
801 std::vector<std::vector<SCH_PIN*>>
m_rows;
814 std::unique_ptr<NUMERIC_EVALUATOR>
m_eval;
820 const std::vector<SCH_PIN*>& aSelectedPins ) :
836 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
837 m_grid->ShowHideColumns(
"0 1 2 3 4 5 9 10" );
841 wxGridCellAttr* attr;
843 attr =
new wxGridCellAttr;
844 attr->SetReadOnly(
true );
847 attr =
new wxGridCellAttr;
854 attr =
new wxGridCellAttr;
861 attr =
new wxGridCellAttr;
868 attr =
new wxGridCellAttr;
869 wxArrayString unitNames;
870 unitNames.push_back( wxGetTranslation(
UNITS_ALL ) );
873 unitNames.push_back(
m_symbol->GetUnitDisplayName( i,
true ) );
878 attr =
new wxGridCellAttr;
879 wxArrayString bodyStyleNames;
880 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALL ) );
884 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_STD ) );
885 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALT ) );
890 bodyStyleNames.push_back( body_style_name );
896 attr =
new wxGridCellAttr;
897 attr->SetRenderer(
new wxGridCellBoolRenderer() );
898 attr->SetEditor(
new wxGridCellBoolEditor() );
899 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
927 GetSizer()->SetSizeHints(
this);
998 m_grid->PopEventHandler(
true );
1015 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1046 if( !
m_grid->CommitPendingChanges() )
1050 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1067 int sortCol = aEvent.GetCol();
1072 if(
m_grid->IsSortingBy( sortCol ) )
1074 ascending = !
m_grid->IsSortOrderAscending();
1086 [&]() -> std::pair<int, int>
1118 m_pins.push_back( newPin );
1140 std::vector<SCH_PIN*> removedRow =
m_dataModel->RemoveRow( row );
1167 if( event.GetRow() >= 0 && event.GetRow() <
m_dataModel->GetNumberRows() )
1169 const std::vector<SCH_PIN*>& pins =
m_dataModel->GetRowPins( event.GetRow() );
1171 if( pins.size() == 1 &&
m_editFrame->GetCurSymbol() )
1175 if( candidate->GetNumber() == pins.at( 0 )->GetNumber() )
1209 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1217 if( !
m_grid->CommitPendingChanges() )
1225 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1239 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1240 _(
"Highlight corresponding pin on canvas when it is selected in the table" ),
1245 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1247 if( menu_id == 0 || menu_id == 4206 )
1256 if( event.IsChecked() )
1271 if( event.IsChecked() )
1286 m_dataModel->SetFilterBySelection( event.IsChecked() );
1326 return std::make_unique<SCH_PIN>( &aSym );
1329 auto colLabelToEnumFn = [](
const wxString& aStr ) ->
COL_ORDER
1336 std::vector<std::unique_ptr<SCH_PIN>> newPins;
1338 if( csvData && csvData->size() >= 2 )
1340 std::vector<COL_ORDER> headerCols;
1341 wxArrayString unknownHeaders;
1343 for(
const wxString& label : ( *csvData )[0] )
1345 COL_ORDER col = colLabelToEnumFn( label );
1348 unknownHeaders.push_back( label );
1350 headerCols.push_back( col );
1353 if( !unknownHeaders.IsEmpty() )
1355 wxString msg = wxString::Format(
_(
"Unknown columns in data: %s. These columns will be ignored." ),
1360 for(
size_t i = 1; i < csvData->size(); ++i )
1362 const std::vector<wxString>& cols = ( *csvData )[i];
1363 std::unique_ptr<SCH_PIN> item = createFn( *
m_symbol );
1365 size_t maxCol = std::min( headerCols.size(), cols.size() );
1367 for(
size_t j = 0; j < maxCol; ++j )
1372 updateFn( *item, cols[j], headerCols[j] );
1375 newPins.emplace_back( std::move( item ) );
1381 int ret = wxMessageBox(
reporter.GetMessages(),
_(
"Errors" ), wxOK | wxCANCEL | wxICON_ERROR,
this );
1384 if( ret == wxCANCEL )
1388 if( !newPins.size() )
1400 for( std::unique_ptr<SCH_PIN>& newPin : newPins )
1401 m_pins.push_back( newPin.release() );
1415 wxString filePath = wxEmptyString;
1419 wxFileName fn(
m_symbol->GetName() );
1422 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1426 if( dlg.ShowModal() == wxID_CANCEL )
1429 filePath = dlg.GetPath();
1432 std::vector<SCH_PIN*> pinsToExport;
1436 for(
int i = 0; i <
m_dataModel->GetNumberRows(); ++i )
1439 pinsToExport.push_back(
pin );
1447 static const std::vector<COL_ORDER> exportCols {
1466 std::vector<std::vector<wxString>>
table;
1467 table.reserve( pinsToExport.size() + 1 );
1469 std::vector<wxString> header;
1470 header.reserve( exportCols.size() );
1473 header.emplace_back( wxGetTranslation(
GetPinTableColLabel(
static_cast<int>( col ) ) ) );
1475 table.emplace_back( std::move( header ) );
1479 std::vector<wxString>& row =
table.emplace_back();
1480 row.reserve( exportCols.size() );
1483 row.emplace_back( fmt.
Format( *
pin,
static_cast<int>( col ) ) );
1495 wxGridUpdateLocker deferRepaintsTillLeavingScope;
1517 width -=
m_grid->GetColSize( i );
1529 wxSize new_size =
event.GetSize();
1545 std::bitset<64> columnsShown =
m_grid->GetShownColumns();
1551 if( !
m_grid->IsCellEditControlShown() )
1555 int firstSelectedRow;
1556 int selectedRowCount;
1574 m_grid->CommitPendingChanges(
true );
1576 int retval = wxID_CANCEL;
1613 if(
pin->GetNumber().Length() )
1617 const wxString summary = pinNumbers.
GetSummary();
1622 m_pin_count->SetLabel( wxString::Format( wxT(
"%u" ), (
unsigned)
m_pins.size() ) );
constexpr EDA_IU_SCALE schIUScale
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
wxRadioButton * m_rbExportOnlyShownPins
STD_BITMAP_BUTTON * m_refreshButton
wxStaticText * m_pin_numbers_summary
wxButton * m_ButtonsCancel
STD_BITMAP_BUTTON * m_addButton
wxStaticText * m_pin_count
wxRadioButton * m_rbReplaceAll
wxStaticText * m_duplicate_pins
wxCheckBox * m_cbFilterSelected
wxChoice * m_bodyStyleFilter
wxCheckBox * m_cbFilterByBodyStyle
STD_BITMAP_BUTTON * m_bMenu
DIALOG_LIB_EDIT_PIN_TABLE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Pin Table"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxCheckBox * m_cbFilterByUnit
wxButton * m_btnExportToFile
STD_BITMAP_BUTTON * m_deleteButton
wxButton * m_groupSelected
wxButton * m_btnImportFromFile
bool m_modified
true when there are unsaved changes
void OnExportButtonClick(wxCommandEvent &event) override
void OnRebuildRows(wxCommandEvent &event) override
int m_originalColWidths[COL_COUNT]
void OnCancel(wxCommandEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) override
void RemovePin(SCH_PIN *pin)
void OnColSort(wxGridEvent &aEvent)
void OnImportButtonClick(wxCommandEvent &event) override
void OnGroupSelected(wxCommandEvent &event) override
void OnClose(wxCloseEvent &event) override
void OnSize(wxSizeEvent &event) override
PIN_TABLE_DATA_MODEL * m_dataModel
DIALOG_LIB_EDIT_PIN_TABLE(SYMBOL_EDIT_FRAME *parent, LIB_SYMBOL *aSymbol, const std::vector< SCH_PIN * > &aSelectedPins)
~DIALOG_LIB_EDIT_PIN_TABLE() override
void OnMenu(wxCommandEvent &event) override
void AddPin(SCH_PIN *pin)
void OnCellSelected(wxGridEvent &event) override
bool TransferDataToWindow() override
void OnAddRow(wxCommandEvent &event) override
void OnDeleteRow(wxCommandEvent &event) override
SYMBOL_EDIT_FRAME * m_editFrame
std::bitset< 64 > m_columnsShown
void OnCellEdited(wxGridEvent &event) override
std::vector< SCH_PIN * > m_pins
bool TransferDataFromWindow() override
void OnFilterCheckBox(wxCommandEvent &event) override
void OnFilterChoice(wxCommandEvent &event) override
void OptOut(wxWindow *aWindow)
Opt out of control state saving.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void EndDialogShim(int aReturnCode)
A mode agnostic way to close a dialog.
The base class for create windows for drawing purpose.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Define a library symbol object.
bool IsMultiBodyStyle() const override
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
const std::vector< wxString > & GetBodyStyleNames() const
bool HasDeMorganBodyStyles() const override
bool IsMultiUnit() const override
int GetBodyStyleCount() const override
The body styles are a property of the drawings, which a derived symbol inherits from its root symbol ...
int GetUnitCount() const override
A singleton reporter that reports to nowhere.
wxString GetDuplicates() const
Gets a formatted string of all the pins that have duplicate numbers.
static int Compare(const wxString &lhs, const wxString &rhs)
void insert(value_type const &v)
wxString GetSummary() const
static bool compare(const std::vector< SCH_PIN * > &lhs, const std::vector< SCH_PIN * > &rhs, int sortCol, bool ascending, EDA_DRAW_FRAME *parentFrame)
void RebuildRows(const std::vector< SCH_PIN * > &aPins, bool groupByName, bool groupBySelection)
void SetUnitFilter(int aFilter)
static int findRow(const std::vector< std::vector< SCH_PIN * > > &aRowSet, const wxString &aName)
std::map< std::pair< std::vector< SCH_PIN * >, int >, wxString > m_evalOriginal
std::vector< std::vector< SCH_PIN * > > m_rows
int GetNumberCols() override
const std::vector< SCH_PIN * > & m_origSelectedPins
The pins in the symbol that are selected at dialog start.
bool IsEmptyCell(int row, int col) override
DIALOG_LIB_EDIT_PIN_TABLE * m_pinTable
std::vector< SCH_PIN * > GetRowPins(int aRow)
static wxString GetValue(const std::vector< SCH_PIN * > &pins, int aCol, EDA_DRAW_FRAME *aParentFrame)
PIN_TABLE_DATA_MODEL(SYMBOL_EDIT_FRAME *aFrame, DIALOG_LIB_EDIT_PIN_TABLE *aPinTable, LIB_SYMBOL *aSymbol, const std::vector< SCH_PIN * > &aOrigSelectedPins)
void AppendRow(SCH_PIN *aPin)
std::unique_ptr< NUMERIC_EVALUATOR > m_eval
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxString GetValue(int aRow, int aCol) override
void SetFilterBySelection(bool aFilter)
void SortRows(int aSortCol, bool ascending)
SYMBOL_EDIT_FRAME * m_frame
int GetNumberRows() override
void onUnitsChanged(wxCommandEvent &aEvent)
void SetBodyStyleFilter(int aFilter)
wxString GetColLabelValue(int aCol) override
std::vector< SCH_PIN * > RemoveRow(int aRow)
void SortPins(std::vector< SCH_PIN * > &aRow)
A pure virtual class used to derive REPORTER objects from.
virtual void SetBodyStyle(int aBodyStyle)
const SYMBOL * GetParentSymbol() const
virtual wxString GetBodyStyleDescription(int aBodyStyle, bool aLabel) const
virtual wxString GetUnitDisplayName(int aUnit, bool aLabel) const
virtual void SetUnit(int aUnit)
int GetNumberTextSize() const
void SetNumber(const wxString &aNumber)
void SetVisible(bool aVisible)
void ChangeLength(int aLength)
Change the length of a pin and adjust its position based on orientation.
void SetOrientation(PIN_ORIENTATION aOrientation)
void SetName(const wxString &aName)
void SetPosition(const VECTOR2I &aPos) override
const wxString & GetName() const
PIN_ORIENTATION GetOrientation() const
void SetNumberTextSize(int aSize)
void SetShape(GRAPHIC_PINSHAPE aShape)
VECTOR2I GetPosition() const override
int GetNameTextSize() const
void SetType(ELECTRICAL_PINTYPE aType)
const wxString & GetNumber() const
GRAPHIC_PINSHAPE GetShape() const
ELECTRICAL_PINTYPE GetType() const
void SetNameTextSize(int aSize)
The symbol library editor main window.
bool IsSymbolGraphicallyEditable() const
Test if a symbol is loaded and can be edited graphically.
A base class for LIB_SYMBOL and SCH_SYMBOL.
int ValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aTextValue in aUnits to internal units used by the frame.
A wrapper for reporting to a wxString object.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
This file is part of the common library.
static wxString GetPinTableColLabel(int aCol)
Get the label for a given column in the pin table.
void getSelectedArea(WX_GRID *aGrid, int *aRowStart, int *aRowCount)
static COL_ORDER GetColTypeForString(const wxString &aStr)
#define CANDIDATE
flag indicating that the structure is connected
static std::map< int, wxString > shapeNames
static const std::string CsvFileExtension
static wxString CsvFileWildcard()
const std::vector< BITMAPS > & PinTypeIcons()
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
const wxArrayString & PinTypeNames()
int PinOrientationIndex(PIN_ORIENTATION code)
const wxArrayString & PinShapeNames()
const std::vector< BITMAPS > & PinShapeIcons()
const wxArrayString & PinOrientationNames()
PIN_ORIENTATION
The symbol library pin object orientations.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
const std::vector< BITMAPS > & PinOrientationIcons()
T * GetAppSettings(const char *aFilename)
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
void AccumulateDescriptions(wxString &aDesc, const T &aItemCollection)
Build a comma-separated list from a collection of wxStrings.
bool crossprobe_on_selection
void WriteTableToFileOrClipboard(const wxString &aToFile, const std::vector< std::vector< wxString > > &aTable)
Write aTable as CSV to aToFile (if non-empty) or to the system clipboard.
std::optional< std::vector< std::vector< wxString > > > ReadTableFromFileOrClipboard(EDA_BASE_FRAME &aFrame, bool aFromFile)
Read a CSV/TSV table from a file selected via a dialog (aFromFile) or from the system clipboard.
IbisParser parser & reporter
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.