26#include <wx/filedlg.h>
27#include <wx/wfstream.h>
29#include <wx/tokenzr.h>
56#define BOOL_TRUE _HKI( "True" )
57#define BOOL_FALSE _HKI( "False" )
83 default: wxFAIL;
return wxEmptyString;
90 return wxGetTranslation( aNativeLabel ).IsSameAs( aStr, aCaseSensitive )
91 || aStr.IsSameAs( aNativeLabel, aCaseSensitive );
150 return wxEmptyString;
184 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
185 return wxEmptyString;
208 if(
PinTypeNames().Index( aValue,
false ) != wxNOT_FOUND )
288 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
303 wxCHECK_MSG(
false, wxEmptyString,
"Invalid BOOL_FORMAT" );
308 if( aValue == wxS(
"1" ) )
312 else if( aValue == wxS(
"0" ) )
325 aReporter.
Report( wxString::Format(
_(
"The value '%s' can't be converted to boolean correctly, "
326 "it has been interpreted as 'False'" ),
341 wxGridCellCoordsArray topLeft = aGrid->GetSelectionBlockTopLeft();
342 wxGridCellCoordsArray botRight = aGrid->GetSelectionBlockBottomRight();
344 wxArrayInt cols = aGrid->GetSelectedCols();
345 wxArrayInt rows = aGrid->GetSelectedRows();
347 if( topLeft.Count() && botRight.Count() )
349 *aRowStart = topLeft[0].GetRow();
350 *aRowCount = botRight[0].GetRow() - *aRowStart + 1;
352 else if( cols.Count() )
355 *aRowCount = aGrid->GetNumberRows();
357 else if( rows.Count() )
359 *aRowStart = rows[0];
360 *aRowCount = rows.Count();
364 *aRowStart = aGrid->GetGridCursorRow();
365 *aRowCount = *aRowStart >= 0 ? 1 : 0;
376 const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
386 m_eval = std::make_unique<NUMERIC_EVALUATOR>(
m_frame->GetUserUnits() );
399 GetView()->ForceRefresh();
423 wxGrid*
grid = GetView();
425 if(
grid->GetGridCursorRow() == aRow &&
grid->GetGridCursorCol() == aCol
426 &&
grid->IsCellEditControlShown() )
462 if( fieldValue.length() )
463 fieldValue += wxT(
", " );
469 if( !fieldValue.Length() )
471 else if( val != fieldValue )
479 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
484 wxString value = aValue;
495 if(
m_eval->Process( value ) )
507 std::vector<SCH_PIN*> pins =
m_rows[ aRow ];
513 wxStringTokenizer tokenizer( value,
"," );
516 while( tokenizer.HasMoreTokens() )
518 wxString pinName = tokenizer.GetNextToken();
521 pinName.Trim(
true ).Trim(
false );
523 if( i < pins.size() )
526 pins.at( i )->SetNumber( pinName );
548 pos.
y -=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
552 pos.
x +=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
558 pins.push_back( newPin );
565 while( pins.size() > i )
588 static int findRow(
const std::vector<std::vector<SCH_PIN*>>& aRowSet,
const wxString& aName )
590 for(
size_t i = 0; i < aRowSet.size(); ++i )
592 if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
599 static bool compare(
const std::vector<SCH_PIN*>& lhs,
const std::vector<SCH_PIN*>& rhs,
602 wxString lhStr =
GetValue( lhs, sortCol, parentFrame );
603 wxString rhStr =
GetValue( rhs, sortCol, parentFrame );
609 lhStr =
GetValue( lhs, sortCol, parentFrame );
610 rhStr =
GetValue( rhs, sortCol, parentFrame );
618 [ ascending ](
const auto a,
const auto b )
655 void RebuildRows(
const std::vector<SCH_PIN*>& aPins,
bool groupByName,
bool groupBySelection )
658 std::vector<SCH_PIN*> clear_flags;
660 clear_flags.reserve( aPins.size() );
664 if( groupBySelection )
667 pin->ClearTempFlags();
669 int firstSelectedRow;
670 int selectedRowCount;
674 for(
int ii = 0; ii < selectedRowCount; ++ii )
679 clear_flags.push_back(
pin );
686 grid->CommitPendingChanges(
true );
688 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
689 GetView()->ProcessTableMessage( msg );
694 if( groupBySelection )
695 m_rows.emplace_back( std::vector<SCH_PIN*>() );
697 std::set<wxString> selectedNumbers;
700 selectedNumbers.insert(
pin->GetNumber() );
703 const auto pinIsInEditorSelection = [&](
SCH_PIN*
pin )
707 if( selectedNumbers.count(
pin->GetNumber() ) == 0 )
717 if( selectedPin->GetNumber() ==
pin->GetNumber()
718 && selectedPin->GetName() ==
pin->GetName()
719 && selectedPin->GetUnit() ==
pin->GetUnit()
720 && selectedPin->GetBodyStyle() ==
pin->GetBodyStyle()
737 if( includedByUnit && includedByBodyStyle && includedBySelection )
743 else if( groupBySelection && (
pin->GetFlags() &
CANDIDATE ) )
748 m_rows.emplace_back( std::vector<SCH_PIN*>() );
749 rowIndex =
m_rows.size() - 1;
757 bool ascending =
true;
759 if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
761 sortCol = GetView()->GetSortingColumn();
762 ascending = GetView()->IsSortOrderAscending();
765 for( std::vector<SCH_PIN*>& row :
m_rows )
768 if( !groupBySelection )
773 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
774 GetView()->ProcessTableMessage( msg );
776 if( groupBySelection )
777 GetView()->SelectRow( 0 );
787 [ aSortCol, ascending,
this ](
const std::vector<SCH_PIN*>& lhs,
788 const std::vector<SCH_PIN*>& rhs ) ->
bool
790 return compare( lhs, rhs, aSortCol, ascending, m_frame );
796 std::sort( aRow.begin(), aRow.end(),
799 return PIN_NUMBERS::Compare( lhs->GetNumber(), rhs->GetNumber() ) < 0;
805 std::vector<SCH_PIN*> row;
806 row.push_back( aPin );
811 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
812 GetView()->ProcessTableMessage( msg );
818 std::vector<SCH_PIN*> removedRow =
m_rows[ aRow ];
824 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
825 GetView()->ProcessTableMessage( msg );
847 std::vector<std::vector<SCH_PIN*>>
m_rows;
860 std::unique_ptr<NUMERIC_EVALUATOR>
m_eval;
873 void ExportData( std::vector<SCH_PIN*>& aPins,
const wxString& aToFile )
const
875 std::vector<int> exportCols {
891 std::vector<std::vector<wxString>> exportTable;
892 exportTable.reserve( aPins.size() + 1 );
894 std::vector<wxString> headers;
895 for(
int col : exportCols )
899 exportTable.emplace_back( std::move( headers ) );
906 std::vector<wxString>& cols = exportTable.emplace_back( 0 );
907 cols.reserve( exportCols.size() );
908 for(
int col : exportCols )
910 cols.emplace_back( formatter.
Format( *
pin, col ) );
914 if( !aToFile.IsEmpty() )
916 wxFileOutputStream os( aToFile );
951 std::vector<std::vector<wxString>> csvData;
954 if( !
path.IsEmpty() )
965 std::vector<std::unique_ptr<SCH_PIN>> pins;
975 for(
size_t i = 1; i < csvData.size(); ++i )
977 std::vector<wxString>& cols = csvData[i];
979 auto pin = std::make_unique<SCH_PIN>( &aSym );
982 size_t maxCol = std::min( headerCols.size(), cols.size() );
984 for(
size_t j = 0; j < maxCol; ++j )
990 formatter.
UpdatePin( *
pin, cols[j], headerCols[j], aSym );
993 pins.emplace_back( std::move(
pin ) );
1003 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
1005 if( dlg.ShowModal() == wxID_CANCEL )
1006 return wxEmptyString;
1008 return dlg.GetPath();
1013 std::vector<COL_ORDER> colOrder;
1014 wxArrayString unknownHeaders;
1016 for(
size_t i = 0; i < aHeaderRow.size(); ++i )
1021 unknownHeaders.push_back( aHeaderRow[i] );
1023 colOrder.push_back( col );
1026 if( unknownHeaders.size() )
1028 wxString msg = wxString::Format(
_(
"Unknown columns in data: %s. These columns will be ignored." ),
1042 const std::vector<SCH_PIN*>& aSelectedPins ) :
1058 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
1063 m_grid->ShowHideColumns( cfg->m_PinTableVisibleColumns );
1068 wxGridCellAttr* attr;
1070 attr =
new wxGridCellAttr;
1071 attr->SetReadOnly(
true );
1074 attr =
new wxGridCellAttr;
1081 attr =
new wxGridCellAttr;
1088 attr =
new wxGridCellAttr;
1095 attr =
new wxGridCellAttr;
1096 wxArrayString unitNames;
1097 unitNames.push_back( wxGetTranslation(
UNITS_ALL ) );
1105 attr =
new wxGridCellAttr;
1106 wxArrayString bodyStyleNames;
1108 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALL ) );
1111 bodyStyleNames.push_back( body_style_name );
1116 attr =
new wxGridCellAttr;
1117 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1118 attr->SetEditor(
new wxGridCellBoolEditor() );
1119 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1140 GetSizer()->SetSizeHints(
this);
1202 cfg->m_PinTableVisibleColumns =
m_grid->GetShownColumnsAsString();
1212 m_grid->PopEventHandler(
true );
1229 std::vector<SCH_PIN*> pins =
m_symbol->GetPins();
1254 if( !
m_grid->CommitPendingChanges() )
1258 std::vector<SCH_PIN*> pins =
m_symbol->GetPins();
1275 int sortCol = aEvent.GetCol();
1280 if(
m_grid->IsSortingBy( sortCol ) )
1282 ascending = !
m_grid->IsSortOrderAscending();
1294 [&]() -> std::pair<int, int>
1325 m_pins.push_back( newPin );
1347 std::vector<SCH_PIN*> removedRow =
m_dataModel->RemoveRow( row );
1374 if( event.GetRow() >= 0 && event.GetRow() <
m_dataModel->GetNumberRows() )
1376 const std::vector<SCH_PIN*>& pins =
m_dataModel->GetRowPins( event.GetRow() );
1378 if( pins.size() == 1 &&
m_editFrame->GetCurSymbol() )
1382 if( candidate->GetNumber() == pins.at( 0 )->GetNumber() )
1411 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1419 if( !
m_grid->CommitPendingChanges() )
1427 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1438 if( event.IsChecked() )
1453 if( event.IsChecked() )
1468 m_dataModel->SetFilterBySelection( event.IsChecked() );
1500 std::vector<std::unique_ptr<SCH_PIN>> newPins = importer.
ImportData( fromFile, *
m_symbol );
1504 int ret = wxMessageBox( reporter.
GetMessages(),
_(
"Errors" ), wxOK | wxCANCEL | wxICON_ERROR,
this );
1507 if( ret == wxCANCEL )
1511 if( !newPins.size() )
1523 for(
auto& newPin : newPins )
1524 m_pins.push_back( newPin.release() );
1538 wxString filePath = wxEmptyString;
1542 wxFileName fn(
m_symbol->GetName() );
1545 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1547 if( dlg.ShowModal() == wxID_CANCEL )
1550 filePath = dlg.GetPath();
1553 std::vector<SCH_PIN*> pinsToExport;
1557 for(
int i = 0; i <
m_dataModel->GetNumberRows(); ++i )
1560 pinsToExport.push_back(
pin );
1569 exporter.
ExportData( pinsToExport, filePath );
1578 wxGridUpdateLocker deferRepaintsTillLeavingScope;
1595 width -=
m_grid->GetColSize( i );
1607 wxSize new_size =
event.GetSize();
1623 std::bitset<64> columnsShown =
m_grid->GetShownColumns();
1629 if( !
m_grid->IsCellEditControlShown() )
1633 int firstSelectedRow;
1634 int selectedRowCount;
1652 m_grid->CommitPendingChanges(
true );
1654 int retval = wxID_CANCEL;
1673 EndDialog( retval );
1688 EndDialog( retval );
1698 if(
pin->GetNumber().Length() )
1703 m_pin_count->SetLabel( wxString::Format( wxT(
"%u" ), (
unsigned)
m_pins.size() ) );
constexpr EDA_IU_SCALE schIUScale
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
void WriteLines(const std::vector< std::vector< wxString > > &aRows)
Write a vector of rows to the stream.
wxRadioButton * m_rbExportOnlyShownPins
STD_BITMAP_BUTTON * m_refreshButton
wxStaticText * m_pin_numbers_summary
BITMAP_BUTTON * m_divider1
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
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 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 SetupStandardButtons(std::map< int, wxString > aLabels={})
bool IsQuasiModal() const
void EndQuasiModal(int retCode)
The base frame for deriving all KiCad main window classes.
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
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)
void ExportData(std::vector< SCH_PIN * > &aPins, const wxString &aToFile) const
UNITS_PROVIDER & m_unitsProvider
PIN_TABLE_EXPORT(UNITS_PROVIDER &aUnitsProvider)
wxString promptForFile() const
std::vector< std::unique_ptr< SCH_PIN > > ImportData(bool aFromFile, LIB_SYMBOL &aSym) const
std::vector< COL_ORDER > getColOrderFromCSV(const std::vector< wxString > &aHeaderRow) const
PIN_TABLE_IMPORT(EDA_BASE_FRAME &aFrame, REPORTER &aReporter)
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
virtual bool HasMessage() const
Returns true if any messages were reported.
virtual void SetBodyStyle(int aBodyStyle)
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 IsSymbolAlias() const
Return true if aLibId is an alias for the editor screen symbol.
SYMBOL_EDITOR_SETTINGS * GetSettings() const
bool IsSymbolEditable() const
Test if a symbol is loaded and can be edited.
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.
const wxString & GetMessages() const
bool SaveTabularDataToClipboard(const std::vector< std::vector< wxString > > &aData)
Store tabular data to the system clipboard.
bool GetTabularDataFromClipboard(std::vector< std::vector< wxString > > &aData)
Attempt to get tabular data from the clipboard.
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.
bool AutoDecodeCSV(const wxString &aInput, std::vector< std::vector< wxString > > &aData)
Try to guess the format of a T/CSV file and decode it into aData.
static wxString GetPinTableColLabel(int aCol)
Get the label for a given column in the pin table.
static bool MatchTranslationOrNative(const wxString &aStr, const wxString &aNativeLabel, bool aCaseSensitive)
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 CsvTsvFileWildcard()
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()
wxString SafeReadFile(const wxString &aFilePath, const wxString &aReadType)
Nominally opens a file and reads it into a string.
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.
#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.