41#include <dialogs/dialog_text_properties.h>
51#include <wx/textdlg.h>
79 wxASSERT_MSG( drawingTools,
"eeschema.SymbolDrawing tool is not available" );
81 auto haveSymbolCondition =
90 if( !
m_frame->IsSymbolEditable() )
105 auto swapSelectionCondition =
117 const auto canConvertStackedPins =
121 if( sel.Size() >= 2 )
123 std::vector<SCH_PIN*> pins;
128 pins.push_back(
static_cast<SCH_PIN*
>( item ) );
132 VECTOR2I pos = pins[0]->GetPosition();
133 for(
size_t i = 1; i < pins.size(); ++i )
135 if( pins[i]->GetPosition() != pos )
142 if( sel.Size() == 1 && sel.Front()->Type() ==
SCH_PIN_T )
152 int coLocatedCount = 0;
156 if(
pin->GetPosition() == pos )
160 if( coLocatedCount >= 2 )
169 const auto canExplodeStackedPin =
172 if( sel.Size() != 1 || sel.Front()->Type() !=
SCH_PIN_T )
177 std::vector<wxString> stackedNumbers =
pin->GetStackedPinNumbers( &isValid );
178 return isValid && stackedNumbers.size() > 1;
265 commit = &localCommit;
275 for(
unsigned ii = 0; ii < selection.
GetSize(); ii++ )
278 item->
Rotate( rotPoint, ccw );
279 m_frame->UpdateItem( item,
false,
true );
291 if( !localCommit.
Empty() )
292 localCommit.
Push(
_(
"Rotate" ) );
317 switch( item->
Type() )
341 m_frame->UpdateItem( item,
false,
true );
347 for(
unsigned ii = 0; ii < selection.
GetSize(); ii++ )
356 m_frame->UpdateItem( item,
false,
true );
379 if( selection.
Size() < 2 )
389 for(
size_t i = 0; i < sorted.size() - 1; i++ )
395 std::swap( aPos, bPos );
422 m_frame->UpdateItem( a,
false,
true );
423 m_frame->UpdateItem( b,
false,
true );
427 for(
EDA_ITEM* selected : selection )
459 std::deque<EDA_ITEM*> items =
m_selectionTool->RequestSelection().GetItems();
470 std::set<SCH_ITEM*> toDelete;
471 int fieldsHidden = 0;
472 int fieldsAlreadyHidden = 0;
481 toDelete.insert( curr_pin );
485 if(
m_frame->SynchronizePins() )
487 std::vector<bool> got_unit( symbol->
GetUnitCount() + 1 );
489 got_unit[curr_pin->
GetUnit()] =
true;
493 if( got_unit[
pin->GetUnit()] )
496 if(
pin->GetPosition() != pos )
508 toDelete.insert(
pin );
509 got_unit[
pin->GetUnit()] =
true;
525 fieldsAlreadyHidden++;
530 toDelete.insert( schItem );
537 if( toDelete.size() == 0 )
539 if( fieldsHidden == 1 )
540 commit.
Push(
_(
"Hide Field" ) );
541 else if( fieldsHidden > 1 )
542 commit.
Push(
_(
"Hide Fields" ) );
543 else if( fieldsAlreadyHidden > 0 )
544 m_frame->ShowInfoBarError(
_(
"Use the Symbol Properties dialog to remove fields." ) );
548 commit.
Push(
_(
"Delete" ) );
569 ( !
m_frame->GetCurSymbol() ||
m_frame->GetCurSymbol()->GetLibId() != treeLibId ) )
580 else if( selection.
Size() == 1 )
588 switch( item->
Type() )
598 bool mouseOverNumber =
false;
601 mouseOverNumber = numberBox->Contains( mousePos );
605 pinTool->EditPinProperties( &
pin, mouseOverNumber );
626 wxFAIL_MSG( wxT(
"Unhandled item <" ) + item->
GetClass() + wxT(
">" ) );
646 m_frame->GetCanvas()->Refresh();
653 std::vector<MSG_PANEL_ITEM> items;
670 m_frame->GetCanvas()->Refresh();
686 m_frame->GetCanvas()->Refresh();
693 if( aField ==
nullptr )
701 caption.Printf(
_(
"Edit '%s' Field" ), aField->
GetName() );
715 commit.
Push( caption );
717 m_frame->GetCanvas()->Refresh();
718 m_frame->UpdateSymbolMsgPanelInfo();
731 if( !bufferedSymbol )
756 wxDataViewItem treeItem = libMgr.
GetAdapter()->FindItem( aLibId );
757 m_frame->UpdateLibraryTree( treeItem, &tempSymbol );
778 m_frame->RebuildSymbolUnitAndBodyStyleLists();
809 wxCHECK( selTool, -1 );
811 std::vector<SCH_PIN*> selectedPins;
820 selectedPins.push_back( pinItem );
833 commit.
Push(
_(
"Edit Pins" ) );
849 wxCHECK( selTool, -1 );
854 std::vector<SCH_PIN*> pinsToConvert;
864 if(
pin->GetPosition() == pos )
865 pinsToConvert.push_back(
pin );
874 pinsToConvert.push_back(
static_cast<SCH_PIN*
>( item ) );
878 if( pinsToConvert.size() < 2 )
880 m_frame->ShowInfoBarError(
_(
"At least two pins are needed to convert to stacked pins" ) );
885 VECTOR2I pos = pinsToConvert[0]->GetPosition();
886 for(
size_t i = 1; i < pinsToConvert.size(); ++i )
888 if( pinsToConvert[i]->GetPosition() != pos )
890 m_frame->ShowInfoBarError(
_(
"All pins must be at the same location" ) );
901 std::sort( pinsToConvert.begin(), pinsToConvert.end(),
904 wxString numA = a->GetNumber();
905 wxString numB = b->GetNumber();
909 bool aIsNumeric = numA.ToLong( &longA );
910 bool bIsNumeric = numB.ToLong( &longB );
913 if( aIsNumeric && bIsNumeric )
914 return longA < longB;
917 if( aIsNumeric && !bIsNumeric )
919 if( !aIsNumeric && bIsNumeric )
927 wxString stackedNotation = wxT(
"[");
930 auto collapseRanges = [&]() -> wxString
932 if( pinsToConvert.empty() )
938 std::map<wxString, std::vector<long>> prefixGroups;
939 std::vector<wxString> nonNumericPins;
944 wxString pinNumber =
pin->GetNumber();
947 if( pinNumber.IsEmpty() )
949 nonNumericPins.push_back( wxT(
"(empty)") );
954 wxString numericPart;
957 size_t numStart = pinNumber.length();
958 for(
int i = pinNumber.length() - 1; i >= 0; i-- )
960 if( !wxIsdigit( pinNumber[i] ) )
969 if( numStart < pinNumber.length() )
971 prefix = pinNumber.Left( numStart );
972 numericPart = pinNumber.Mid( numStart );
975 if( numericPart.ToLong( &numValue ) && numValue >= 0 )
977 prefixGroups[prefix].push_back( numValue );
982 nonNumericPins.push_back( pinNumber );
987 nonNumericPins.push_back( pinNumber );
992 for(
auto& [prefix, numbers] : prefixGroups )
998 std::sort( numbers.begin(), numbers.end() );
1002 while( i < numbers.size() )
1007 long start = numbers[i];
1011 while( i + 1 < numbers.size() && numbers[i + 1] == numbers[i] + 1 )
1018 if(
end > start + 1 )
1019 result += wxString::Format( wxT(
"%s%ld-%s%ld"), prefix, start, prefix,
end );
1020 else if(
end == start + 1 )
1021 result += wxString::Format( wxT(
"%s%ld,%s%ld"), prefix, start, prefix,
end );
1023 result += wxString::Format( wxT(
"%s%ld"), prefix, start );
1030 for(
const wxString& nonNum : nonNumericPins )
1040 stackedNotation += collapseRanges();
1041 stackedNotation += wxT(
"]");
1044 SCH_PIN* masterPin = pinsToConvert[0];
1045 masterPin->
SetNumber( stackedNotation );
1049 wxString::Format(
"Converting %zu pins to stacked notation '%s'",
1050 pinsToConvert.size(), stackedNotation ) );
1054 std::vector<SCH_PIN*> pinsToRemove;
1055 for(
size_t i = 1; i < pinsToConvert.size(); ++i )
1057 SCH_PIN* pinToRemove = pinsToConvert[i];
1061 wxString::Format(
"Will remove pin '%s' at position (%d, %d)",
1066 pinsToRemove.push_back( pinToRemove );
1075 commit.
Push( wxString::Format(
_(
"Convert %zu Stacked Pins to '%s'" ),
1076 pinsToConvert.size(), stackedNotation ) );
1091 wxCHECK( selTool, -1 );
1097 m_frame->ShowInfoBarError(
_(
"Select a single pin with stacked notation to explode" ) );
1105 std::vector<wxString> stackedNumbers =
pin->GetStackedPinNumbers( &isValid );
1107 if( !isValid || stackedNumbers.size() <= 1 )
1109 m_frame->ShowInfoBarError(
_(
"Selected pin does not have valid stacked notation" ) );
1119 std::sort( stackedNumbers.begin(), stackedNumbers.end(),
1120 [](
const wxString& a,
const wxString& b )
1124 if( a.ToLong( &numA ) && b.ToLong( &numB ) )
1132 pin->SetNumber( stackedNumbers[0] );
1133 pin->SetVisible(
true );
1136 for(
size_t i = 1; i < stackedNumbers.size(); ++i )
1158 commit.
Push(
_(
"Explode Stacked Pin" ) );
1173 m_frame->ShowInfoBarError(
_(
"Symbol is not derived from another symbol." ) );
1195 m_frame->GetSymbolFromUndoList();
1211 m_frame->GetSymbolFromRedoList();
1221 int retVal =
Copy( aEvent );
1235 if( !symbol || !selection.
GetSize() )
1245 if( !item.IsSelected() )
1259 std::string prettyData = formatter.
GetString();
1274 if( selection.Empty() )
1279 if( selection.IsHover() )
1300 if( newParts.empty() || !newParts[0] )
1303 newPart = newParts[0];
1310 wxString pasteText( clipboardData );
1314 if( pasteText.Length() > 5000 )
1315 pasteText = pasteText.Left( 5000 ) + wxT(
"..." );
1351 if( !selection.
Empty() )
1356 commit.
Push(
_(
"Paste" ) );
1371 if( selection.
GetSize() == 0 )
1376 std::vector<EDA_ITEM*> oldItems;
1377 std::vector<EDA_ITEM*> newItems;
1379 std::copy( selection.
begin(), selection.
end(), std::back_inserter( oldItems ) );
1380 std::sort( oldItems.begin(), oldItems.end(), [](
EDA_ITEM* a,
EDA_ITEM* b )
1384 if( a->Type() != b->Type() )
1385 return a->Type() < b->Type();
1388 if( a->Type() == SCH_PIN_T )
1390 const wxString& aNum = static_cast<SCH_PIN*>( a )->GetNumber();
1391 const wxString& bNum = static_cast<SCH_PIN*>( b )->GetNumber();
1393 cmp = StrNumCmp( aNum, bNum );
1397 if( aNum.IsNumber() && bNum.IsNumber() && cmp != 0 )
1419 newPin->
SetNumber( wxString::Format( wxT(
"%i" ), symbol->GetMaxPinNumber() + 1 ) );
1425 newItems.push_back( newItem );
1427 symbol->AddDrawItem( newItem );
1428 getView()->Add( newItem );
1434 selection.SetReferencePoint( getViewControls()->GetCursorPosition(
true ) );
1437 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.
A logical library item identifier and consists of various portions much like a URI.
bool IsValid() const
Check if this LID_ID is valid.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Symbol library management helper that is specific to the symbol library editor frame.
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > & GetAdapter()
Return the adapter object that provides the stored data.
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.
LIB_SYMBOL * GetBufferedSymbol(const wxString &aSymbolName, const wxString &aLibrary)
Return the symbol copy from the buffer.
void SetSymbolModified(const wxString &aSymbolName, const wxString &aLibrary)
bool UpdateSymbol(LIB_SYMBOL *aSymbol, const wxString &aLibrary)
Update the symbol buffer with a new version of the symbol.
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)