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;
174 if( !parent->IsMultiUnit() )
186 if( !parent->IsMultiBodyStyle() )
196 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
197 return wxEmptyString;
220 if(
PinTypeNames().Index( aValue,
false ) != wxNOT_FOUND )
264 if( !parent->IsMultiUnit() )
289 if( !parent->IsMultiBodyStyle() )
312 wxFAIL_MSG( wxString::Format(
"Invalid field id %d", aFieldId ) );
323 return aValue ? wxT(
"1" ) : wxT(
"0" );
327 wxFAIL_MSG(
"Invalid BOOL_FORMAT" );
328 return wxEmptyString;
335 if( aValue == wxS(
"1" ) )
337 else if( aValue == wxS(
"0" ) )
344 aReporter.
Report( wxString::Format(
_(
"The value '%s' can't be converted to boolean correctly, "
345 "it has been interpreted as 'False'" ),
360 wxGridCellCoordsArray topLeft = aGrid->GetSelectionBlockTopLeft();
361 wxGridCellCoordsArray botRight = aGrid->GetSelectionBlockBottomRight();
363 wxArrayInt cols = aGrid->GetSelectedCols();
364 wxArrayInt rows = aGrid->GetSelectedRows();
366 if( topLeft.Count() && botRight.Count() )
368 *aRowStart = topLeft[0].GetRow();
369 *aRowCount = botRight[0].GetRow() - *aRowStart + 1;
371 else if( cols.Count() )
374 *aRowCount = aGrid->GetNumberRows();
376 else if( rows.Count() )
378 *aRowStart = rows[0];
379 *aRowCount = rows.Count();
383 *aRowStart = aGrid->GetGridCursorRow();
384 *aRowCount = *aRowStart >= 0 ? 1 : 0;
395 const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
405 m_eval = std::make_unique<NUMERIC_EVALUATOR>(
m_frame->GetUserUnits() );
418 GetView()->ForceRefresh();
442 wxGrid*
grid = GetView();
444 if(
grid->GetGridCursorRow() == aRow &&
grid->GetGridCursorCol() == aCol &&
grid->IsCellEditControlShown() )
480 if( fieldValue.length() )
481 fieldValue += wxT(
", " );
487 if( !fieldValue.Length() )
489 else if( val != fieldValue )
497 void SetValue(
int aRow,
int aCol,
const wxString &aValue )
override
502 wxString value = aValue;
513 if(
m_eval->Process( value ) )
525 std::vector<SCH_PIN*> pins =
m_rows[ aRow ];
531 wxStringTokenizer tokenizer( value,
"," );
534 while( tokenizer.HasMoreTokens() )
536 wxString pinName = tokenizer.GetNextToken();
539 pinName.Trim(
true ).Trim(
false );
541 if( i < pins.size() )
544 pins.at( i )->SetNumber( pinName );
566 pos.
y -=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
570 pos.
x +=
schIUScale.MilsToIU( cfg->m_Repeat.pin_step );
576 pins.push_back( newPin );
583 while( pins.size() > i )
604 static int findRow(
const std::vector<std::vector<SCH_PIN*>>& aRowSet,
const wxString& aName )
606 for(
size_t i = 0; i < aRowSet.size(); ++i )
608 if( aRowSet[ i ][ 0 ] && aRowSet[ i ][ 0 ]->GetName() == aName )
615 static bool compare(
const std::vector<SCH_PIN*>& lhs,
const std::vector<SCH_PIN*>& rhs,
618 wxString lhStr =
GetValue( lhs, sortCol, parentFrame );
619 wxString rhStr =
GetValue( rhs, sortCol, parentFrame );
625 lhStr =
GetValue( lhs, sortCol, parentFrame );
626 rhStr =
GetValue( rhs, sortCol, parentFrame );
634 [ ascending ](
const auto a,
const auto b )
671 void RebuildRows(
const std::vector<SCH_PIN*>& aPins,
bool groupByName,
bool groupBySelection )
674 std::vector<SCH_PIN*> clear_flags;
676 clear_flags.reserve( aPins.size() );
680 if( groupBySelection )
683 pin->ClearTempFlags();
685 int firstSelectedRow;
686 int selectedRowCount;
690 for(
int ii = 0; ii < selectedRowCount; ++ii )
695 clear_flags.push_back(
pin );
702 grid->CommitPendingChanges(
true );
704 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0,
m_rows.size() );
705 GetView()->ProcessTableMessage( msg );
710 if( groupBySelection )
711 m_rows.emplace_back( std::vector<SCH_PIN*>() );
713 std::set<wxString> selectedNumbers;
716 selectedNumbers.insert(
pin->GetNumber() );
718 const auto pinIsInEditorSelection =
723 if( selectedNumbers.count(
pin->GetNumber() ) == 0 )
731 if( selectedPin->GetNumber() ==
pin->GetNumber()
732 && selectedPin->GetName() ==
pin->GetName()
733 && selectedPin->GetUnit() ==
pin->GetUnit()
734 && selectedPin->GetBodyStyle() ==
pin->GetBodyStyle() )
749 if( includedByUnit && includedByBodyStyle && includedBySelection )
755 else if( groupBySelection && (
pin->GetFlags() &
CANDIDATE ) )
760 m_rows.emplace_back( std::vector<SCH_PIN*>() );
761 rowIndex =
m_rows.size() - 1;
769 bool ascending =
true;
771 if( GetView() && GetView()->GetSortingColumn() != wxNOT_FOUND )
773 sortCol = GetView()->GetSortingColumn();
774 ascending = GetView()->IsSortOrderAscending();
777 for( std::vector<SCH_PIN*>& row :
m_rows )
780 if( !groupBySelection )
785 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (
int)
m_rows.size() );
786 GetView()->ProcessTableMessage( msg );
788 if( groupBySelection )
789 GetView()->SelectRow( 0 );
799 [ aSortCol, ascending,
this ](
const std::vector<SCH_PIN*>& lhs,
800 const std::vector<SCH_PIN*>& rhs ) ->
bool
802 return compare( lhs, rhs, aSortCol, ascending, m_frame );
808 std::sort( aRow.begin(), aRow.end(),
811 return PIN_NUMBERS::Compare( lhs->GetNumber(), rhs->GetNumber() ) < 0;
817 std::vector<SCH_PIN*> row;
818 row.push_back( aPin );
823 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
824 GetView()->ProcessTableMessage( msg );
830 std::vector<SCH_PIN*> removedRow =
m_rows[ aRow ];
836 wxGridTableMessage msg(
this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aRow, 1 );
837 GetView()->ProcessTableMessage( msg );
859 std::vector<std::vector<SCH_PIN*>>
m_rows;
872 std::unique_ptr<NUMERIC_EVALUATOR>
m_eval;
885 void ExportData( std::vector<SCH_PIN*>& aPins,
const wxString& aToFile )
const
887 std::vector<int> exportCols {
903 std::vector<std::vector<wxString>> exportTable;
904 exportTable.reserve( aPins.size() + 1 );
906 std::vector<wxString> headers;
907 for(
int col : exportCols )
911 exportTable.emplace_back( std::move( headers ) );
918 std::vector<wxString>& cols = exportTable.emplace_back( 0 );
919 cols.reserve( exportCols.size() );
920 for(
int col : exportCols )
922 cols.emplace_back( formatter.
Format( *
pin, col ) );
926 if( !aToFile.IsEmpty() )
928 wxFileOutputStream os( aToFile );
964 std::vector<std::vector<wxString>> csvData;
967 if( !
path.IsEmpty() )
978 std::vector<std::unique_ptr<SCH_PIN>> pins;
988 for(
size_t i = 1; i < csvData.size(); ++i )
990 std::vector<wxString>& cols = csvData[i];
992 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( &aSym );
995 size_t maxCol = std::min( headerCols.size(), cols.size() );
997 for(
size_t j = 0; j < maxCol; ++j )
1003 formatter.
UpdatePin( *
pin, cols[j], headerCols[j], aSym );
1006 pins.emplace_back( std::move(
pin ) );
1017 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
1021 if( dlg.ShowModal() == wxID_CANCEL )
1022 return wxEmptyString;
1024 return dlg.GetPath();
1029 std::vector<COL_ORDER> colOrder;
1030 wxArrayString unknownHeaders;
1032 for(
size_t i = 0; i < aHeaderRow.size(); ++i )
1037 unknownHeaders.push_back( aHeaderRow[i] );
1039 colOrder.push_back( col );
1042 if( unknownHeaders.size() )
1044 wxString msg = wxString::Format(
_(
"Unknown columns in data: %s. These columns will be ignored." ),
1058 const std::vector<SCH_PIN*>& aSelectedPins ) :
1074 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
1075 m_grid->ShowHideColumns(
"0 1 2 3 4 5 9 10" );
1079 wxGridCellAttr* attr;
1081 attr =
new wxGridCellAttr;
1082 attr->SetReadOnly(
true );
1085 attr =
new wxGridCellAttr;
1092 attr =
new wxGridCellAttr;
1099 attr =
new wxGridCellAttr;
1106 attr =
new wxGridCellAttr;
1107 wxArrayString unitNames;
1108 unitNames.push_back( wxGetTranslation(
UNITS_ALL ) );
1111 unitNames.push_back(
m_symbol->GetUnitDisplayName( i,
true ) );
1116 attr =
new wxGridCellAttr;
1117 wxArrayString bodyStyleNames;
1118 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALL ) );
1122 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_STD ) );
1123 bodyStyleNames.push_back( wxGetTranslation(
DEMORGAN_ALT ) );
1128 bodyStyleNames.push_back( body_style_name );
1134 attr =
new wxGridCellAttr;
1135 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1136 attr->SetEditor(
new wxGridCellBoolEditor() );
1137 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1157 GetSizer()->SetSizeHints(
this);
1226 m_grid->PopEventHandler(
true );
1243 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1258 if( !
m_grid->CommitPendingChanges() )
1262 std::vector<SCH_PIN*> pins =
m_symbol->GetGraphicalPins( 0, 0 );
1279 int sortCol = aEvent.GetCol();
1284 if(
m_grid->IsSortingBy( sortCol ) )
1286 ascending = !
m_grid->IsSortOrderAscending();
1298 [&]() -> std::pair<int, int>
1330 m_pins.push_back( newPin );
1352 std::vector<SCH_PIN*> removedRow =
m_dataModel->RemoveRow( row );
1379 if( event.GetRow() >= 0 && event.GetRow() <
m_dataModel->GetNumberRows() )
1381 const std::vector<SCH_PIN*>& pins =
m_dataModel->GetRowPins( event.GetRow() );
1383 if( pins.size() == 1 &&
m_editFrame->GetCurSymbol() )
1387 if( candidate->GetNumber() == pins.at( 0 )->GetNumber() )
1421 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1429 if( !
m_grid->CommitPendingChanges() )
1437 m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1451 menu.Append( 4206,
_(
"Highlight on Cross-probe" ),
1452 _(
"Highlight corresponding pin on canvas when it is selected in the table" ),
1457 int menu_id =
m_bMenu->GetPopupMenuSelectionFromUser( menu );
1459 if( menu_id == 0 || menu_id == 4206 )
1468 if( event.IsChecked() )
1483 if( event.IsChecked() )
1498 m_dataModel->SetFilterBySelection( event.IsChecked() );
1530 std::vector<std::unique_ptr<SCH_PIN>> newPins = importer.
ImportData( fromFile, *
m_symbol );
1534 int ret = wxMessageBox( reporter.
GetMessages(),
_(
"Errors" ), wxOK | wxCANCEL | wxICON_ERROR,
this );
1537 if( ret == wxCANCEL )
1541 if( !newPins.size() )
1553 for( std::unique_ptr<SCH_PIN>& newPin : newPins )
1554 m_pins.push_back( newPin.release() );
1568 wxString filePath = wxEmptyString;
1572 wxFileName fn(
m_symbol->GetName() );
1575 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1579 if( dlg.ShowModal() == wxID_CANCEL )
1582 filePath = dlg.GetPath();
1585 std::vector<SCH_PIN*> pinsToExport;
1589 for(
int i = 0; i <
m_dataModel->GetNumberRows(); ++i )
1592 pinsToExport.push_back(
pin );
1601 exporter.
ExportData( pinsToExport, filePath );
1610 wxGridUpdateLocker deferRepaintsTillLeavingScope;
1627 width -=
m_grid->GetColSize( i );
1639 wxSize new_size =
event.GetSize();
1655 std::bitset<64> columnsShown =
m_grid->GetShownColumns();
1661 if( !
m_grid->IsCellEditControlShown() )
1665 int firstSelectedRow;
1666 int selectedRowCount;
1684 m_grid->CommitPendingChanges(
true );
1686 int retval = wxID_CANCEL;
1705 EndDialog( retval );
1720 EndDialog( retval );
1730 if(
pin->GetNumber().Length() )
1735 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 bool HasMessage() const
Returns true if any messages were reported.
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.
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.
bool crossprobe_on_selection
#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.