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;
334 const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
344 m_eval = std::make_unique<NUMERIC_EVALUATOR>(
m_frame->GetUserUnits() );
357 GetView()->ForceRefresh();
381 wxGrid*
grid = GetView();
383 if(
grid->GetGridCursorRow() == aRow &&
grid->GetGridCursorCol() == aCol &&
grid->IsCellEditControlShown() )
419 if( fieldValue.length() )
420 fieldValue += wxT(
", " );
426 if( !fieldValue.Length() )
428 else if( val != fieldValue )
436 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
441 wxString value = aValue;
452 if(
m_eval->Process( value ) )
464 std::vector<SCH_PIN*> pins =
m_rows[ aRow ];
470 wxStringTokenizer tokenizer( value,
"," );
473 while( tokenizer.HasMoreTokens() )
475 wxString pinName = tokenizer.GetNextToken();
478 pinName.Trim(
true ).Trim(
false );
480 if( i < pins.size() )
483 pins.at( i )->SetNumber( pinName );
505 pos.
y -=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
509 pos.
x +=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
515 pins.push_back( newPin );
522 while( pins.size() > i )
543 static int findRow(
const std::vector<std::vector<SCH_PIN*>>& aRowSet,
const wxString& aName )
545 for(
size_t i = 0; i < aRowSet.size(); ++i )
547 if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
554 static bool compare(
const std::vector<SCH_PIN*>& lhs,
const std::vector<SCH_PIN*>& rhs,
557 wxString lhStr =
GetValue( lhs, sortCol, parentFrame );
558 wxString rhStr =
GetValue( rhs, sortCol, parentFrame );
564 lhStr =
GetValue( lhs, sortCol, parentFrame );
565 rhStr =
GetValue( rhs, sortCol, parentFrame );
573 [ ascending ](
const auto a,
const auto b )
610 void RebuildRows(
const std::vector<SCH_PIN*>& aPins,
bool groupByName,
bool groupBySelection )
613 std::vector<SCH_PIN*> clear_flags;
615 clear_flags.reserve( aPins.size() );
619 if( groupBySelection )
622 pin->ClearTempFlags();
624 int firstSelectedRow;
625 int selectedRowCount;
629 for(
int ii = 0; ii < selectedRowCount; ++ii )
634 clear_flags.push_back(
pin );
641 grid->CommitPendingChanges(
true );
643 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
644 GetView()->ProcessTableMessage( msg );
649 if( groupBySelection )
650 m_rows.emplace_back( std::vector<SCH_PIN*>() );
652 std::set<wxString> selectedNumbers;
655 selectedNumbers.insert(
pin->GetNumber() );
657 const auto pinIsInEditorSelection =
662 if( selectedNumbers.count(
pin->GetNumber() ) == 0 )
670 if( selectedPin->GetNumber() ==
pin->GetNumber()
671 && selectedPin->GetName() ==
pin->GetName()
672 && selectedPin->GetUnit() ==
pin->GetUnit()
673 && selectedPin->GetBodyStyle() ==
pin->GetBodyStyle() )
691 || pinIsInEditorSelection(
pin );
693 if( includedByUnit && includedByBodyStyle && includedBySelection )
699 else if( groupBySelection && (
pin->GetFlags() &
CANDIDATE ) )
704 m_rows.emplace_back( std::vector<SCH_PIN*>() );
705 rowIndex =
m_rows.size() - 1;
713 bool ascending =
true;
715 if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
717 sortCol = GetView()->GetSortingColumn();
718 ascending = GetView()->IsSortOrderAscending();
721 for( std::vector<SCH_PIN*>& row :
m_rows )
724 if( !groupBySelection )
729 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
730 GetView()->ProcessTableMessage( msg );
732 if( groupBySelection )
733 GetView()->SelectRow( 0 );
743 [ aSortCol, ascending,
this ](
const std::vector<SCH_PIN*>& lhs,
744 const std::vector<SCH_PIN*>& rhs ) ->
bool
746 return compare( lhs, rhs, aSortCol, ascending, m_frame );
752 std::sort( aRow.begin(), aRow.end(),
755 return PIN_NUMBERS::Compare( lhs->GetNumber(), rhs->GetNumber() ) < 0;
761 std::vector<SCH_PIN*> row;
762 row.push_back( aPin );
767 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
768 GetView()->ProcessTableMessage( msg );
776 std::vector<SCH_PIN*> removedRow =
m_rows[ aRow ];
782 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
783 GetView()->ProcessTableMessage( msg );
806 std::vector<std::vector<SCH_PIN*>>
m_rows;
819 std::unique_ptr<NUMERIC_EVALUATOR>
m_eval;
825 const std::vector<SCH_PIN*>& aSelectedPins ) :
841 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
842 m_grid->ShowHideColumns(
"0 1 2 3 4 5 9 10" );
846 wxGridCellAttr* attr;
848 attr =
new wxGridCellAttr;
849 attr->SetReadOnly(
true );
852 attr =
new wxGridCellAttr;
859 attr =
new wxGridCellAttr;
866 attr =
new wxGridCellAttr;
873 attr =
new wxGridCellAttr;
874 wxArrayString unitNames;
875 unitNames.push_back( wxGetTranslation(
UNITS_ALL ) );
878 unitNames.push_back(
m_symbol->GetUnitDisplayName( i,
true ) );
883 attr =
new wxGridCellAttr;
884 wxArrayString bodyStyleNames;
885 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALL ) );
889 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_STD ) );
890 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALT ) );
895 bodyStyleNames.push_back( body_style_name );
901 attr =
new wxGridCellAttr;
902 attr->SetRenderer(
new wxGridCellBoolRenderer() );
903 attr->SetEditor(
new wxGridCellBoolEditor() );
904 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
932 GetSizer()->SetSizeHints(
this);
1007 m_grid->PopEventHandler(
true );
1024 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1055 if( !
m_grid->CommitPendingChanges() )
1059 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1076 int sortCol = aEvent.GetCol();
1081 if(
m_grid->IsSortingBy( sortCol ) )
1083 ascending = !
m_grid->IsSortOrderAscending();
1095 [&]() -> std::pair<int, int>
1127 m_pins.push_back( newPin );
1149 std::vector<SCH_PIN*> removedRow =
m_dataModel->RemoveRow( row );
1176 if( event.GetRow() >= 0 && event.GetRow() <
m_dataModel->GetNumberRows() )
1178 const std::vector<SCH_PIN*>& pins =
m_dataModel->GetRowPins( event.GetRow() );
1180 if( pins.size() == 1 &&
m_editFrame->GetCurSymbol() )
1184 if( candidate->GetNumber() == pins.at( 0 )->GetNumber() )
1204 if( event.GetEventType() == wxEVT_GRID_EDITOR_SHOWN )
1222 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1230 if( !
m_grid->CommitPendingChanges() )
1238 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1252 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1253 _(
"Highlight corresponding pin on canvas when it is selected in the table" ),
1258 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1260 if( menu_id == 0 || menu_id == 4206 )
1269 if( event.IsChecked() )
1284 if( event.IsChecked() )
1299 m_dataModel->SetFilterBySelection( event.IsChecked() );
1325 if( !
m_grid->CommitPendingChanges() )
1344 return std::make_unique<SCH_PIN>( &aSym );
1347 auto colLabelToEnumFn =
1355 std::vector<std::unique_ptr<SCH_PIN>> newPins;
1357 if( csvData && csvData->size() >= 2 )
1359 std::vector<COL_ORDER> headerCols;
1360 wxArrayString unknownHeaders;
1362 for(
const wxString& label : ( *csvData )[0] )
1364 COL_ORDER col = colLabelToEnumFn( label );
1367 unknownHeaders.push_back( label );
1369 headerCols.push_back( col );
1372 if( !unknownHeaders.IsEmpty() )
1374 wxString msg = wxString::Format(
_(
"Unknown columns in data: %s. These columns will be ignored." ),
1379 for(
size_t i = 1; i < csvData->size(); ++i )
1381 const std::vector<wxString>& cols = ( *csvData )[i];
1382 std::unique_ptr<SCH_PIN> item = createFn( *
m_symbol );
1384 size_t maxCol = std::min( headerCols.size(), cols.size() );
1386 for(
size_t j = 0; j < maxCol; ++j )
1391 updateFn( *item, cols[j], headerCols[j] );
1394 newPins.emplace_back( std::move( item ) );
1400 int ret = wxMessageBox(
reporter.GetMessages(),
_(
"Errors" ), wxOK | wxCANCEL | wxICON_ERROR,
this );
1403 if( ret == wxCANCEL )
1407 if( !newPins.size() )
1419 for( std::unique_ptr<SCH_PIN>& newPin : newPins )
1420 m_pins.push_back( newPin.release() );
1432 if( !
m_grid->CommitPendingChanges() )
1438 wxString filePath = wxEmptyString;
1442 wxFileName fn(
m_symbol->GetName() );
1445 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1449 if( dlg.ShowModal() == wxID_CANCEL )
1452 filePath = dlg.GetPath();
1455 std::vector<SCH_PIN*> pinsToExport;
1459 for(
int i = 0; i <
m_dataModel->GetNumberRows(); ++i )
1462 pinsToExport.push_back(
pin );
1470 static const std::vector<COL_ORDER> exportCols {
1489 std::vector<std::vector<wxString>>
table;
1490 table.reserve( pinsToExport.size() + 1 );
1492 std::vector<wxString> header;
1493 header.reserve( exportCols.size() );
1496 header.emplace_back( wxGetTranslation(
GetPinTableColLabel(
static_cast<int>( col ) ) ) );
1498 table.emplace_back( std::move( header ) );
1502 std::vector<wxString>& row =
table.emplace_back();
1503 row.reserve( exportCols.size() );
1506 row.emplace_back( fmt.
Format( *
pin,
static_cast<int>( col ) ) );
1518 wxGridUpdateLocker deferRepaintsTillLeavingScope;
1540 width -=
m_grid->GetColSize( i );
1552 wxSize new_size =
event.GetSize();
1568 std::bitset<64> columnsShown =
m_grid->GetShownColumns();
1574 if( !
m_grid->IsCellEditControlShown() )
1578 int firstSelectedRow;
1579 int selectedRowCount;
1597 m_grid->CommitPendingChanges(
true );
1599 int retval = wxID_CANCEL;
1636 if(
pin->GetNumber().Length() )
1640 const wxString summary = pinNumbers.
GetSummary();
1645 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
wxButton * m_btnImportFromClipboard
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.