41#include <dialogs/dialog_text_properties.h> 
   50#include <wx/textdlg.h>      
   78    wxASSERT_MSG( drawingTools, 
"eeschema.SymbolDrawing tool is not available" );
 
   80    auto haveSymbolCondition =
 
   89                if( !
m_frame->IsSymbolEditable() )
 
  104    auto swapSelectionCondition =
 
  116    const auto canConvertStackedPins =
 
  120                if( sel.Size() >= 2 )
 
  122                    std::vector<SCH_PIN*> pins;
 
  127                        pins.push_back( 
static_cast<SCH_PIN*
>( item ) );
 
  131                    VECTOR2I pos = pins[0]->GetPosition();
 
  132                    for( 
size_t i = 1; i < pins.size(); ++i )
 
  134                        if( pins[i]->GetPosition() != pos )
 
  141                if( sel.Size() == 1 && sel.Front()->Type() == 
SCH_PIN_T )
 
  151                    int coLocatedCount = 0;
 
  155                        if( 
pin->GetPosition() == pos )
 
  159                            if( coLocatedCount >= 2 )
 
  168    const auto canExplodeStackedPin =
 
  171                if( sel.Size() != 1 || sel.Front()->Type() != 
SCH_PIN_T )
 
  176                std::vector<wxString> stackedNumbers = 
pin->GetStackedPinNumbers( &isValid );
 
  177                return isValid && stackedNumbers.size() > 1;
 
 
  264        commit = &localCommit;
 
  274    for( 
unsigned ii = 0; ii < selection.
GetSize(); ii++ )
 
  277        item->
Rotate( rotPoint, ccw );
 
  278        m_frame->UpdateItem( item, 
false, 
true );
 
  290        if( !localCommit.
Empty() )
 
  291            localCommit.
Push( 
_( 
"Rotate" ) );
 
 
  316        switch( item->
Type() )
 
  340        m_frame->UpdateItem( item, 
false, 
true );
 
  346        for( 
unsigned ii = 0; ii < selection.
GetSize(); ii++ )
 
  355            m_frame->UpdateItem( item, 
false, 
true );
 
 
  378    if( selection.
Size() < 2 )
 
  388    for( 
size_t i = 0; i < sorted.size() - 1; i++ )
 
  394        std::swap( aPos, bPos );
 
  421        m_frame->UpdateItem( a, 
false, 
true );
 
  422        m_frame->UpdateItem( b, 
false, 
true );
 
  426    for( 
EDA_ITEM* selected : selection )
 
 
  458    std::deque<EDA_ITEM*> items = 
m_selectionTool->RequestSelection().GetItems();
 
  469    std::set<SCH_ITEM*> toDelete;
 
  470    int                 fieldsHidden = 0;
 
  471    int                 fieldsAlreadyHidden = 0;
 
  480            toDelete.insert( curr_pin );
 
  484            if( 
m_frame->SynchronizePins() )
 
  486                std::vector<bool> got_unit( symbol->
GetUnitCount() + 1 );
 
  488                got_unit[curr_pin->
GetUnit()] = 
true;
 
  492                    if( got_unit[
pin->GetUnit()] )
 
  495                    if( 
pin->GetPosition() != pos )
 
  507                    toDelete.insert( 
pin );
 
  508                    got_unit[
pin->GetUnit()] = 
true;
 
  524                fieldsAlreadyHidden++;
 
  529            toDelete.insert( schItem );
 
  536    if( toDelete.size() == 0 )
 
  538        if( fieldsHidden == 1 )
 
  539            commit.
Push( 
_( 
"Hide Field" ) );
 
  540        else if( fieldsHidden > 1 )
 
  541            commit.
Push( 
_( 
"Hide Fields" ) );
 
  542        else if( fieldsAlreadyHidden > 0 )
 
  543            m_frame->ShowInfoBarError( 
_( 
"Use the Symbol Properties dialog to remove fields." ) );
 
  547        commit.
Push( 
_( 
"Delete" ) );
 
 
  564    else if( selection.
Size() == 1 )
 
  572        switch( item->
Type() )
 
  582            bool mouseOverNumber = 
false;
 
  585                mouseOverNumber = numberBox->Contains( mousePos );
 
  589                pinTool->EditPinProperties( &
pin, mouseOverNumber );
 
  610            wxFAIL_MSG( wxT( 
"Unhandled item <" ) + item->
GetClass() + wxT( 
">" ) );
 
 
  630    m_frame->GetCanvas()->Refresh();
 
  637    std::vector<MSG_PANEL_ITEM> items;
 
 
  654    m_frame->GetCanvas()->Refresh();
 
 
  670    m_frame->GetCanvas()->Refresh();
 
 
  677    if( aField == 
nullptr )
 
  685        caption.Printf( 
_( 
"Edit '%s' Field" ), aField->
GetName() );
 
  699    commit.
Push( caption );
 
  701    m_frame->GetCanvas()->Refresh();
 
  702    m_frame->UpdateSymbolMsgPanelInfo();
 
 
  723    m_frame->RebuildSymbolUnitAndBodyStyleLists();
 
 
  754    wxCHECK( selTool, -1 );
 
  756    std::vector<SCH_PIN*> selectedPins;
 
  765            selectedPins.push_back( pinItem );
 
  778    commit.
Push( 
_( 
"Edit Pins" ) );
 
 
  794    wxCHECK( selTool, -1 );
 
  799    std::vector<SCH_PIN*> pinsToConvert;
 
  809            if( 
pin->GetPosition() == pos )
 
  810                pinsToConvert.push_back( 
pin );
 
  819                pinsToConvert.push_back( 
static_cast<SCH_PIN*
>( item ) );
 
  823    if( pinsToConvert.size() < 2 )
 
  825        m_frame->ShowInfoBarError( 
_( 
"At least two pins are needed to convert to stacked pins" ) );
 
  830    VECTOR2I pos = pinsToConvert[0]->GetPosition();
 
  831    for( 
size_t i = 1; i < pinsToConvert.size(); ++i )
 
  833        if( pinsToConvert[i]->GetPosition() != pos )
 
  835            m_frame->ShowInfoBarError( 
_( 
"All pins must be at the same location" ) );
 
  846    std::sort( pinsToConvert.begin(), pinsToConvert.end(),
 
  849            wxString numA = a->GetNumber();
 
  850            wxString numB = b->GetNumber();
 
  854            bool aIsNumeric = numA.ToLong( &longA );
 
  855            bool bIsNumeric = numB.ToLong( &longB );
 
  858            if( aIsNumeric && bIsNumeric )
 
  859                return longA < longB;
 
  862            if( aIsNumeric && !bIsNumeric )
 
  864            if( !aIsNumeric && bIsNumeric )
 
  872    wxString stackedNotation = wxT(
"[");
 
  875    auto collapseRanges = [&]() -> wxString
 
  877        if( pinsToConvert.empty() )
 
  883        std::map<wxString, std::vector<long>> prefixGroups;
 
  884        std::vector<wxString> nonNumericPins;
 
  889            wxString pinNumber = 
pin->GetNumber();
 
  892            if( pinNumber.IsEmpty() )
 
  894                nonNumericPins.push_back( wxT(
"(empty)") );
 
  899            wxString numericPart;
 
  902            size_t numStart = pinNumber.length();
 
  903            for( 
int i = pinNumber.length() - 1; i >= 0; i-- )
 
  905                if( !wxIsdigit( pinNumber[i] ) )
 
  914            if( numStart < pinNumber.length() )  
 
  916                prefix = pinNumber.Left( numStart );
 
  917                numericPart = pinNumber.Mid( numStart );
 
  920                if( numericPart.ToLong( &numValue ) && numValue >= 0 )  
 
  922                    prefixGroups[prefix].push_back( numValue );
 
  927                    nonNumericPins.push_back( pinNumber );
 
  932                nonNumericPins.push_back( pinNumber );
 
  937        for( 
auto& [prefix, numbers] : prefixGroups )
 
  943            std::sort( numbers.begin(), numbers.end() );
 
  947            while( i < numbers.size() )
 
  952                long start = numbers[i];
 
  956                while( i + 1 < numbers.size() && numbers[i + 1] == numbers[i] + 1 )
 
  963                if( 
end > start + 1 )  
 
  964                    result += wxString::Format( wxT(
"%s%ld-%s%ld"), prefix, start, prefix, 
end );
 
  965                else if( 
end == start + 1 )  
 
  966                    result += wxString::Format( wxT(
"%s%ld,%s%ld"), prefix, start, prefix, 
end );
 
  968                    result += wxString::Format( wxT(
"%s%ld"), prefix, start );
 
  975        for( 
const wxString& nonNum : nonNumericPins )
 
  985    stackedNotation += collapseRanges();
 
  986    stackedNotation += wxT(
"]");
 
  989    SCH_PIN* masterPin = pinsToConvert[0];
 
  994               wxString::Format( 
"Converting %zu pins to stacked notation '%s'",
 
  995                               pinsToConvert.size(), stackedNotation ) );
 
  999    std::vector<SCH_PIN*> pinsToRemove;
 
 1000    for( 
size_t i = 1; i < pinsToConvert.size(); ++i )
 
 1002        SCH_PIN* pinToRemove = pinsToConvert[i];
 
 1006           wxString::Format( 
"Will remove pin '%s' at position (%d, %d)",
 
 1011        pinsToRemove.push_back( pinToRemove );
 
 1020    commit.
Push( wxString::Format( 
_( 
"Convert %zu Stacked Pins to '%s'" ),
 
 1021                                  pinsToConvert.size(), stackedNotation ) );
 
 
 1036    wxCHECK( selTool, -1 );
 
 1042        m_frame->ShowInfoBarError( 
_( 
"Select a single pin with stacked notation to explode" ) );
 
 1050    std::vector<wxString> stackedNumbers = 
pin->GetStackedPinNumbers( &isValid );
 
 1052    if( !isValid || stackedNumbers.size() <= 1 )
 
 1054        m_frame->ShowInfoBarError( 
_( 
"Selected pin does not have valid stacked notation" ) );
 
 1064    std::sort( stackedNumbers.begin(), stackedNumbers.end(),
 
 1065        []( 
const wxString& a, 
const wxString& b )
 
 1069            if( a.ToLong( &numA ) && b.ToLong( &numB ) )
 
 1077    pin->SetNumber( stackedNumbers[0] );
 
 1078    pin->SetVisible( 
true );
 
 1081    for( 
size_t i = 1; i < stackedNumbers.size(); ++i )
 
 1103    commit.
Push( 
_( 
"Explode Stacked Pin" ) );
 
 
 1118        m_frame->ShowInfoBarError( 
_( 
"Symbol is not derived from another symbol." ) );
 
 
 1140        m_frame->GetSymbolFromUndoList();
 
 
 1156        m_frame->GetSymbolFromRedoList();
 
 
 1166    int retVal = 
Copy( aEvent );
 
 
 1180    if( !symbol || !selection.
GetSize() )
 
 1190        if( !item.IsSelected() )
 
 1204    std::string prettyData = formatter.
GetString();
 
 
 1219    if( selection.Empty() )
 
 1224    if( selection.IsHover() )
 
 
 1245        if( newParts.empty() || !newParts[0] )
 
 1248        newPart = newParts[0];
 
 1255        wxString pasteText( clipboardData );
 
 1259        if( pasteText.Length() > 5000 )
 
 1260            pasteText = pasteText.Left( 5000 ) + wxT( 
"..." );
 
 1296    if( !selection.
Empty() )
 
 1301            commit.
Push( 
_( 
"Paste" ) );
 
 
 1316    if( selection.
GetSize() == 0 )
 
 1321    std::vector<EDA_ITEM*> oldItems;
 
 1322    std::vector<EDA_ITEM*> newItems;
 
 1324    std::copy( selection.
begin(), selection.
end(), std::back_inserter( oldItems ) );
 
 1325    std::sort( oldItems.begin(), oldItems.end(), []( 
EDA_ITEM* a, 
EDA_ITEM* b )
 
 1329        if( a->Type() != b->Type() )
 
 1330            return a->Type() < b->Type();
 
 1333        if( a->Type() == SCH_PIN_T )
 
 1335            const wxString& aNum = static_cast<SCH_PIN*>( a )->GetNumber();
 
 1336            const wxString& bNum = static_cast<SCH_PIN*>( b )->GetNumber();
 
 1338            cmp = StrNumCmp( aNum, bNum );
 
 1342            if( aNum.IsNumber() && bNum.IsNumber() && cmp != 0 )
 
 1364                newPin->
SetNumber( wxString::Format( wxT( 
"%i" ), symbol->GetMaxPinNumber() + 1 ) );
 
 1370        newItems.push_back( newItem );
 
 1372        symbol->AddDrawItem( newItem );
 
 1373        getView()->Add( newItem );
 
 1379    selection.SetReferencePoint( getViewControls()->GetCursorPosition( 
true ) );
 
 1382        commit.Push( 
_( 
"Duplicate" ) );
 
 
std::optional< BOX2I > OPT_BOX2I
 
static TOOL_ACTION decrementPrimary
 
static TOOL_ACTION cancelInteractive
 
static TOOL_ACTION unselectAll
 
static TOOL_ACTION decrementSecondary
 
static TOOL_ACTION incrementSecondary
 
static TOOL_ACTION duplicate
 
static TOOL_ACTION incrementPrimary
 
static TOOL_ACTION doDelete
 
static TOOL_ACTION deleteTool
 
static TOOL_ACTION increment
 
static TOOL_ACTION selectionClear
Clear the current selection.
 
static TOOL_ACTION copyAsText
 
static TOOL_ACTION refreshPreview
 
static TOOL_ACTION selectAll
 
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
 
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
 
This class is setup in expectation of its children possibly using Kiway player so DIALOG_SHIM::ShowQu...
 
void UpdateField(SCH_FIELD *aField)
 
bool GetApplyToAllConversions()
 
bool GetApplyToAllUnits()
 
Dialog to update or change schematic library symbols.
 
A base class for most all the KiCad significant classes used in schematics and boards.
 
virtual VECTOR2I GetPosition() const
 
virtual void SetPosition(const VECTOR2I &aPos)
 
EDA_ITEM_FLAGS GetEditFlags() const
 
void SetFlags(EDA_ITEM_FLAGS aMask)
 
KICAD_T Type() const
Returns the type of object.
 
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
 
virtual void SetParent(EDA_ITEM *aParent)
 
EDA_ITEM * GetParent() const
 
virtual bool IsVisible() const
 
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
 
GR_TEXT_H_ALIGN_T GetHorizJustify() const
 
virtual void SetVisible(bool aVisible)
 
GR_TEXT_V_ALIGN_T GetVertJustify() const
 
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
 
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
 
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
 
Define a library symbol object.
 
bool UnitsLocked() const
Check whether symbol units are interchangeable.
 
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
 
void RemoveDrawItem(SCH_ITEM *aItem)
Remove draw aItem from list.
 
std::vector< SCH_PIN * > GetPins() const override
 
int GetUnitCount() const override
 
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
 
A pin layout helper is a class that manages the layout of the parts of a pin on a schematic symbol:
 
OPT_BOX2I GetPinNumberBBox()
Get the bounding box of the pin number, if there is one.
 
static TOOL_ACTION rotateCCW
 
static TOOL_ACTION mirrorV
 
static TOOL_ACTION convertStackedPins
 
static TOOL_ACTION pinTable
 
static TOOL_ACTION properties
 
static TOOL_ACTION rotateCW
 
static TOOL_ACTION mirrorH
 
static TOOL_ACTION symbolProperties
 
static TOOL_ACTION explodeStackedPin
 
static TOOL_ACTION updateSymbolFields
 
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
 
virtual void Revert() override
Revert the commit by restoring the modified items state.
 
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
 
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
 
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
 
Base class for any item which can be embedded within the SCHEMATIC container class,...
 
SCH_ITEM * Duplicate(bool addToParentGroup, SCH_COMMIT *aCommit=nullptr, bool doClone=false) const
Routine to create a new copy of given item.
 
virtual void SetBodyStyle(int aBodyStyle)
 
virtual void MirrorHorizontally(int aCenter)
Mirror item horizontally about aCenter.
 
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
 
virtual void SetUnit(int aUnit)
 
wxString GetClass() const override
Return the class name.
 
virtual void MirrorVertically(int aCenter)
Mirror item vertically about aCenter.
 
void SetNumber(const wxString &aNumber)
 
void SetVisible(bool aVisible)
 
void SetOrientation(PIN_ORIENTATION aOrientation)
 
void SetName(const wxString &aName)
 
void SetPosition(const VECTOR2I &aPos) override
 
const wxString & GetName() const
 
void SetLength(int aLength)
 
PIN_ORIENTATION GetOrientation() const
 
void SetNumberTextSize(int aSize)
 
void SetShape(GRAPHIC_PINSHAPE aShape)
 
VECTOR2I GetPosition() const override
 
void SetType(ELECTRICAL_PINTYPE aType)
 
const wxString & GetNumber() const
 
ELECTRICAL_PINTYPE GetType() const
 
void SetNameTextSize(int aSize)
 
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
 
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
 
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
 
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
 
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
 
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
 
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
 
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
 
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
 
virtual unsigned int GetSize() const override
Return the number of stored items.
 
virtual void Clear() override
Remove all the stored items from the group.
 
int Size() const
Returns the number of selected parts.
 
std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
 
void SetReferencePoint(const VECTOR2I &aP)
 
bool Empty() const
Checks if there is anything selected.
 
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
 
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
 
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
 
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
 
#define IS_NEW
New item, just created.
 
#define SELECTED
Item was manually selected by the user.
 
#define STRUCT_DELETED
flag indication structures to be erased
 
const wxChar *const traceStackedPins
Flag to enable debug output for stacked pins handling in symbol/pin code.
 
PIN_ORIENTATION
The symbol library pin object orientations.
 
wxString TitleCaps(const wxString &aString)
Capitalize the first letter in each word.
 
wxString result
Test unit parsing edge cases and error handling.
 
constexpr GR_TEXT_H_ALIGN_T GetFlippedAlignment(GR_TEXT_H_ALIGN_T aAlign)
Get the reverse alignment: left-right are swapped, others are unchanged.
 
wxLogTrace helper definitions.
 
VECTOR2< int32_t > VECTOR2I
 
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)