22#include <wx/filedlg.h>
23#include <wx/wfstream.h>
25#include <wx/tokenzr.h>
52#define BOOL_TRUE _HKI( "True" )
53#define BOOL_FALSE _HKI( "False" )
79 default: wxFAIL;
return wxEmptyString;
86 return wxGetTranslation( aNativeLabel ).IsSameAs( aStr, aCaseSensitive )
87 || aStr.IsSameAs( aNativeLabel, aCaseSensitive );
146 return wxEmptyString;
170 if( !parent->IsMultiUnit() )
182 if( !parent->IsMultiBodyStyle() )
192 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
193 return wxEmptyString;
216 if(
PinTypeNames().Index( aValue,
false ) != wxNOT_FOUND )
260 if( !parent->IsMultiUnit() )
285 if( !parent->IsMultiBodyStyle() )
308 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
319 return aValue ? wxT(
"1" ) : wxT(
"0" );
323 wxFAIL_MSG(
"Invalid BOOL_FORMAT" );
324 return wxEmptyString;
331 if( aValue == wxS(
"1" ) )
333 else if( aValue == wxS(
"0" ) )
340 aReporter.
Report( wxString::Format(
_(
"The value '%s' can't be converted to boolean correctly, "
341 "it has been interpreted as 'False'" ),
356 wxGridCellCoordsArray topLeft = aGrid->GetSelectionBlockTopLeft();
357 wxGridCellCoordsArray botRight = aGrid->GetSelectionBlockBottomRight();
359 wxArrayInt cols = aGrid->GetSelectedCols();
360 wxArrayInt rows = aGrid->GetSelectedRows();
362 if( topLeft.Count() && botRight.Count() )
364 *aRowStart = topLeft[0].GetRow();
365 *aRowCount = botRight[0].GetRow() - *aRowStart + 1;
367 else if( cols.Count() )
370 *aRowCount = aGrid->GetNumberRows();
372 else if( rows.Count() )
374 *aRowStart = rows[0];
375 *aRowCount = rows.Count();
379 *aRowStart = aGrid->GetGridCursorRow();
380 *aRowCount = *aRowStart >= 0 ? 1 : 0;
391 const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
401 m_eval = std::make_unique<NUMERIC_EVALUATOR>(
m_frame->GetUserUnits() );
414 GetView()->ForceRefresh();
438 wxGrid*
grid = GetView();
440 if(
grid->GetGridCursorRow() == aRow &&
grid->GetGridCursorCol() == aCol &&
grid->IsCellEditControlShown() )
476 if( fieldValue.length() )
477 fieldValue += wxT(
", " );
483 if( !fieldValue.Length() )
485 else if( val != fieldValue )
493 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
498 wxString value = aValue;
509 if(
m_eval->Process( value ) )
521 std::vector<SCH_PIN*> pins =
m_rows[ aRow ];
527 wxStringTokenizer tokenizer( value,
"," );
530 while( tokenizer.HasMoreTokens() )
532 wxString pinName = tokenizer.GetNextToken();
535 pinName.Trim(
true ).Trim(
false );
537 if( i < pins.size() )
540 pins.at( i )->SetNumber( pinName );
562 pos.
y -=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
566 pos.
x +=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
572 pins.push_back( newPin );
579 while( pins.size() > i )
600 static int findRow(
const std::vector<std::vector<SCH_PIN*>>& aRowSet,
const wxString& aName )
602 for(
size_t i = 0; i < aRowSet.size(); ++i )
604 if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
611 static bool compare(
const std::vector<SCH_PIN*>& lhs,
const std::vector<SCH_PIN*>& rhs,
614 wxString lhStr =
GetValue( lhs, sortCol, parentFrame );
615 wxString rhStr =
GetValue( rhs, sortCol, parentFrame );
621 lhStr =
GetValue( lhs, sortCol, parentFrame );
622 rhStr =
GetValue( rhs, sortCol, parentFrame );
630 [ ascending ](
const auto a,
const auto b )
667 void RebuildRows(
const std::vector<SCH_PIN*>& aPins,
bool groupByName,
bool groupBySelection )
670 std::vector<SCH_PIN*> clear_flags;
672 clear_flags.reserve( aPins.size() );
676 if( groupBySelection )
679 pin->ClearTempFlags();
681 int firstSelectedRow;
682 int selectedRowCount;
686 for(
int ii = 0; ii < selectedRowCount; ++ii )
691 clear_flags.push_back(
pin );
698 grid->CommitPendingChanges(
true );
700 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
701 GetView()->ProcessTableMessage( msg );
706 if( groupBySelection )
707 m_rows.emplace_back( std::vector<SCH_PIN*>() );
709 std::set<wxString> selectedNumbers;
712 selectedNumbers.insert(
pin->GetNumber() );
714 const auto pinIsInEditorSelection =
719 if( selectedNumbers.count(
pin->GetNumber() ) == 0 )
727 if( selectedPin->GetNumber() ==
pin->GetNumber()
728 && selectedPin->GetName() ==
pin->GetName()
729 && selectedPin->GetUnit() ==
pin->GetUnit()
730 && selectedPin->GetBodyStyle() ==
pin->GetBodyStyle() )
745 if( includedByUnit && includedByBodyStyle && includedBySelection )
751 else if( groupBySelection && (
pin->GetFlags() &
CANDIDATE ) )
756 m_rows.emplace_back( std::vector<SCH_PIN*>() );
757 rowIndex =
m_rows.size() - 1;
765 bool ascending =
true;
767 if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
769 sortCol = GetView()->GetSortingColumn();
770 ascending = GetView()->IsSortOrderAscending();
773 for( std::vector<SCH_PIN*>& row :
m_rows )
776 if( !groupBySelection )
781 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
782 GetView()->ProcessTableMessage( msg );
784 if( groupBySelection )
785 GetView()->SelectRow( 0 );
795 [ aSortCol, ascending,
this ](
const std::vector<SCH_PIN*>& lhs,
796 const std::vector<SCH_PIN*>& rhs ) ->
bool
798 return compare( lhs, rhs, aSortCol, ascending, m_frame );
804 std::sort( aRow.begin(), aRow.end(),
807 return PIN_NUMBERS::Compare( lhs->GetNumber(), rhs->GetNumber() ) < 0;
813 std::vector<SCH_PIN*> row;
814 row.push_back( aPin );
819 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
820 GetView()->ProcessTableMessage( msg );
826 std::vector<SCH_PIN*> removedRow =
m_rows[ aRow ];
832 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
833 GetView()->ProcessTableMessage( msg );
855 std::vector<std::vector<SCH_PIN*>>
m_rows;
868 std::unique_ptr<NUMERIC_EVALUATOR>
m_eval;
881 void ExportData( std::vector<SCH_PIN*>& aPins,
const wxString& aToFile )
const
883 std::vector<int> exportCols {
899 std::vector<std::vector<wxString>> exportTable;
900 exportTable.reserve( aPins.size() + 1 );
902 std::vector<wxString> headers;
903 for(
int col : exportCols )
907 exportTable.emplace_back( std::move( headers ) );
914 std::vector<wxString>& cols = exportTable.emplace_back( 0 );
915 cols.reserve( exportCols.size() );
916 for(
int col : exportCols )
918 cols.emplace_back( formatter.
Format( *
pin, col ) );
922 if( !aToFile.IsEmpty() )
924 wxFileOutputStream os( aToFile );
960 std::vector<std::vector<wxString>> csvData;
963 if( !
path.IsEmpty() )
974 std::vector<std::unique_ptr<SCH_PIN>> pins;
984 for(
size_t i = 1; i < csvData.size(); ++i )
986 std::vector<wxString>& cols = csvData[i];
988 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( &aSym );
991 size_t maxCol = std::min( headerCols.size(), cols.size() );
993 for(
size_t j = 0; j < maxCol; ++j )
999 formatter.
UpdatePin( *
pin, cols[j], headerCols[j], aSym );
1002 pins.emplace_back( std::move(
pin ) );
1013 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
1017 if( dlg.ShowModal() == wxID_CANCEL )
1018 return wxEmptyString;
1020 return dlg.GetPath();
1025 std::vector<COL_ORDER> colOrder;
1026 wxArrayString unknownHeaders;
1028 for(
size_t i = 0; i < aHeaderRow.size(); ++i )
1033 unknownHeaders.push_back( aHeaderRow[i] );
1035 colOrder.push_back( col );
1038 if( unknownHeaders.size() )
1040 wxString msg = wxString::Format(
_(
"Unknown columns in data: %s. These columns will be ignored." ),
1054 const std::vector<SCH_PIN*>& aSelectedPins ) :
1070 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
1071 m_grid->ShowHideColumns(
"0 1 2 3 4 5 9 10" );
1075 wxGridCellAttr* attr;
1077 attr =
new wxGridCellAttr;
1078 attr->SetReadOnly(
true );
1081 attr =
new wxGridCellAttr;
1088 attr =
new wxGridCellAttr;
1095 attr =
new wxGridCellAttr;
1102 attr =
new wxGridCellAttr;
1103 wxArrayString unitNames;
1104 unitNames.push_back( wxGetTranslation(
UNITS_ALL ) );
1107 unitNames.push_back(
m_symbol->GetUnitDisplayName( i,
true ) );
1112 attr =
new wxGridCellAttr;
1113 wxArrayString bodyStyleNames;
1114 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALL ) );
1118 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_STD ) );
1119 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALT ) );
1124 bodyStyleNames.push_back( body_style_name );
1130 attr =
new wxGridCellAttr;
1131 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1132 attr->SetEditor(
new wxGridCellBoolEditor() );
1133 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1163 GetSizer()->SetSizeHints(
this);
1232 m_grid->PopEventHandler(
true );
1249 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1264 if( !
m_grid->CommitPendingChanges() )
1268 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1285 int sortCol = aEvent.GetCol();
1290 if(
m_grid->IsSortingBy( sortCol ) )
1292 ascending = !
m_grid->IsSortOrderAscending();
1304 [&]() -> std::pair<int, int>
1336 m_pins.push_back( newPin );
1358 std::vector<SCH_PIN*> removedRow =
m_dataModel->RemoveRow( row );
1385 if( event.GetRow() >= 0 && event.GetRow() <
m_dataModel->GetNumberRows() )
1387 const std::vector<SCH_PIN*>& pins =
m_dataModel->GetRowPins( event.GetRow() );
1389 if( pins.size() == 1 &&
m_editFrame->GetCurSymbol() )
1393 if( candidate->GetNumber() == pins.at( 0 )->GetNumber() )
1427 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1435 if( !
m_grid->CommitPendingChanges() )
1443 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1457 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1458 _(
"Highlight corresponding pin on canvas when it is selected in the table" ),
1463 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1465 if( menu_id == 0 || menu_id == 4206 )
1474 if( event.IsChecked() )
1489 if( event.IsChecked() )
1504 m_dataModel->SetFilterBySelection( event.IsChecked() );
1536 std::vector<std::unique_ptr<SCH_PIN>> newPins = importer.
ImportData( fromFile, *
m_symbol );
1540 int ret = wxMessageBox(
reporter.GetMessages(),
_(
"Errors" ), wxOK | wxCANCEL | wxICON_ERROR,
this );
1543 if( ret == wxCANCEL )
1547 if( !newPins.size() )
1559 for( std::unique_ptr<SCH_PIN>& newPin : newPins )
1560 m_pins.push_back( newPin.release() );
1574 wxString filePath = wxEmptyString;
1578 wxFileName fn(
m_symbol->GetName() );
1581 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1585 if( dlg.ShowModal() == wxID_CANCEL )
1588 filePath = dlg.GetPath();
1591 std::vector<SCH_PIN*> pinsToExport;
1595 for(
int i = 0; i <
m_dataModel->GetNumberRows(); ++i )
1598 pinsToExport.push_back(
pin );
1607 exporter.
ExportData( pinsToExport, filePath );
1616 wxGridUpdateLocker deferRepaintsTillLeavingScope;
1638 width -=
m_grid->GetColSize( i );
1650 wxSize new_size =
event.GetSize();
1666 std::bitset<64> columnsShown =
m_grid->GetShownColumns();
1672 if( !
m_grid->IsCellEditControlShown() )
1676 int firstSelectedRow;
1677 int selectedRowCount;
1695 m_grid->CommitPendingChanges(
true );
1697 int retval = wxID_CANCEL;
1716 EndDialog( retval );
1731 EndDialog( retval );
1741 if(
pin->GetNumber().Length() )
1745 const wxString summary = pinNumbers.
GetSummary();
1750 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
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 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 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 IsSymbolAlias() const
Return true if aLibId is an alias for the editor screen symbol.
bool IsSymbolEditable() const
Test if a symbol is loaded and can be edited.
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 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.
bool crossprobe_on_selection
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.