50#define QUIET_MODE true
55 m_inMoveTool( false ),
56 m_moveInProgress( false ),
105 bool foundAttachment =
false;
106 bool foundJunction =
false;
107 bool foundPin =
false;
112 foundAttachment =
true;
116 switch( cItem->Type() )
132 if( !foundLine && cLine->
GetLength() == 0 )
138 foundJunction =
true;
156 bool preferOriginalLine =
false;
160 && line->GetLength() == 0
163 preferOriginalLine =
true;
169 else if( !foundLine && foundJunction && !foundPin )
172 foundLine =
new SCH_LINE( unselectedEnd, line->GetLayer() );
188 if( foundLine && !preferOriginalLine )
209 else if( foundLine->
GetEndPoint() == unselectedEnd )
210 foundLine->
MoveEnd( splitDelta );
266 line->MoveStart( splitDelta );
271 else if( line->GetLength() == 0 )
281 else if( foundAttachment && line->IsOrthogonal() )
288 unsigned int xMoveBit = splitDelta.
x != 0;
289 unsigned int yMoveBit = splitDelta.
y != 0;
290 int xLength = abs( unselectedEnd.
x - selectedEnd.
x );
291 int yLength = abs( unselectedEnd.
y - selectedEnd.
y );
292 int xMove = ( xLength - ( xBendCount * lineGrid.
x ) )
293 *
sign( selectedEnd.
x - unselectedEnd.
x );
294 int yMove = ( yLength - ( yBendCount * lineGrid.
y ) )
295 *
sign( selectedEnd.
y - unselectedEnd.
y );
315 xBendCount += yMoveBit;
316 yBendCount += xMoveBit;
321 line->MoveEnd(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
322 splitDelta.
y ? splitDelta.
y : yMove ) );
326 line->MoveStart(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
327 splitDelta.
y ? splitDelta.
y : yMove ) );
348 else if( !foundAttachment )
351 line->MoveEnd( splitDelta );
353 line->MoveStart( splitDelta );
365 bool isSlice =
false;
407 if( sel && !sel->
IsNew() )
416 controls->SetAutoPan(
false );
440 bool unselect = selection.
IsHover();
443 std::vector<DANGLING_END_ITEM> internalPoints;
448 controls->ShowCursor(
true );
452 if( selection.
Empty() )
460 bool restore_state =
false;
466 m_cursor = controls->GetCursorPosition();
485 bool placingNewItems = sch_item && sch_item->
IsNew();
493 internalPoints.clear();
500 if( !it->IsSelected() )
513 std::vector<SCH_ITEM*> stageTwo;
515 for(
EDA_ITEM* edaItem : selection )
518 std::vector<VECTOR2I> connections;
520 switch( item->
Type() )
526 stageTwo.emplace_back(item);
530 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
536 for(
const VECTOR2I& point : connections )
544 for(
const VECTOR2I& point : item->GetConnectionPoints() )
548 for(
EDA_ITEM* item : connectedDragItems )
556 for(
EDA_ITEM* edaItem : selection )
577 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
580 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( internalPoints );
585 snapLayer =
grid.GetSelectionGrid( selection );
593 else if( item->GetParent() && item->GetParent()->IsSelected() )
608 m_cursor = controls->GetCursorPosition();
612 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
614 else if( placingNewItems )
622 bool isPasted =
false;
628 if( item->GetParent() && item->GetParent()->IsSelected() )
634 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
642 selection.SetReferencePoint(
m_cursor );
659 selection.SetReferencePoint(
m_cursor );
668 controls->SetCursorPosition(
m_cursor,
false );
671 controls->SetAutoPan(
true );
678 m_cursor =
grid.BestSnapAnchor( controls->GetCursorPosition(
false ),
679 snapLayer, selection );
689 std::vector<VECTOR2I> splitMoves;
720 for(
const VECTOR2I& splitDelta : splitMoves )
723 if( splitDelta ==
VECTOR2I( 0, 0 ) )
730 if( item->GetParent() && item->GetParent()->IsSelected() )
755 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
756 lineEnd.first->SetStartPoint(
pin->GetPosition() );
757 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
758 lineEnd.first->SetEndPoint(
pin->GetPosition() );
794 restore_state =
true;
870 }
while( ( evt =
Wait() ) );
878 selectionCopy.
Add( line );
881 selectionCopy.
Add( line );
886 newLine->ClearEditFlags();
893 oldLine->ClearEditFlags();
898 controls->ForceCursorPosition(
false );
899 controls->ShowCursor(
false );
900 controls->SetAutoPan(
false );
917 sch_item->SetConnectivityDirty(
true );
920 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
950 item->ClearEditFlags();
954 for(
EDA_ITEM* item : selectionCopy )
955 item->ClearEditFlags();
967 return !restore_state;
976 std::set<SCH_ITEM*> danglers;
978 std::function<void(
SCH_ITEM* )> changeHandler =
979 [&](
SCH_ITEM* aChangedItem ) ->
void
986 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
987 && !aChangedItem->IsSelected() )
989 danglers.insert( aChangedItem );
1019 for(
SCH_ITEM* item : itemsOverlapping )
1021 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1024 foundJunction = item;
1030 if( foundSymbol && foundJunction )
1032 aList.push_back( foundSymbol );
1038 aList.push_back( foundJunction );
1045 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1048 switch(
test->Type() )
1064 if(
test->IsConnected( aPoint ) )
1065 aList.push_back(
test );
1071 aList.push_back(
test );
1084 if(
pin->IsConnected( aPoint ) )
1094 if(
test->IsConnected( aPoint ) )
1095 aList.push_back(
test );
1110 aList.push_back( label );
1122 if( line->
HitTest( aPoint, 1 ) )
1123 aList.push_back( label );
1140 std::vector<SCH_ITEM*> itemsConnectable;
1141 bool ptHasUnselectedJunction =
false;
1164 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1166 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1176 auto makeNewJunction =
1193 for(
SCH_ITEM* item : itemsOverlappingRTree )
1197 if( item == aSelectedItem || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1203 itemsConnectable.push_back( item );
1206 for(
SCH_ITEM* item : itemsConnectable )
1208 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1210 ptHasUnselectedJunction =
true;
1227 if( ptHasUnselectedJunction )
1247 aList.push_back( line );
1261 aList.push_back( line );
1266 switch( aSelectedItem->
Type() )
1280 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1283 aList.push_back( newWire );
1288 if( !line->
IsNew() )
1294 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1295 makeNewJunction( aCommit, line, aPoint );
1327 aList.push_back( label );
1330 info.attachedLine = line;
1342 if(
pin->IsConnected( aPoint ) )
1353 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1355 aList.push_back( newWire );
1364 if(
test->IsConnected( aPoint ) && !newWire )
1368 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1370 aList.push_back( newWire );
1379 aList.push_back(
test );
1415 aList.push_back( label );
1420 info.attachedLine = line;
1427 else if(
test->IsConnected( aPoint ) && !newWire )
1431 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1433 aList.push_back( newWire );
1459 if( line->
HitTest( point, 1 ) )
1462 aList.push_back(
test );
1465 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1468 if( ends[0] == point )
1492 switch( aItem->
Type() )
1534 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1535 pin->ConstrainOnEdge(
pin->GetStoredPos(), true );
1549 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1554 label->
Move( aDelta );
1561 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1594 if( !it->IsSelected() )
1597 if( !selection.
IsHover() && it->IsSelected() )
1600 it->SetStoredPos( it->GetPosition() );
1605 pin->SetStoredPos(
pin->GetPosition() );
1617 for(
int ii = 0; ii < 2; ++ii )
1624 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1630 for(
EDA_ITEM* dragItem : unique_items )
1632 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1635 doMoveItem( dragItem,
delta );
1645 doMoveItem( item,
delta );
1652 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1653 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1657 doMoveItem( sheet, tl_delta );
1668 if(
pin->GetSide() == SHEET_SIDE::TOP ||
pin->GetSide() == SHEET_SIDE::LEFT )
1669 newPos =
pin->GetPosition() + tl_delta;
1671 newPos =
pin->GetPosition() + br_delta;
1683 for(
EDA_ITEM* dragItem : drag_items )
1685 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1688 doMoveItem( dragItem,
delta );
1699 for(
const VECTOR2I& point : connections )
1702 std::map<VECTOR2I, int> shifts;
1706 for(
const VECTOR2I& conn : connections )
1708 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
1712 if( shifts[gridpt] > max_count )
1714 most_common = gridpt;
1715 max_count = shifts[most_common];
1719 if( most_common !=
VECTOR2I( 0, 0 ) )
1721 doMoveItem( item, most_common );
1723 for(
EDA_ITEM* dragItem : drag_items )
1725 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1728 doMoveItem( dragItem, most_common );
1741 commit.
Push(
_(
"Align" ) );
static TOOL_ACTION duplicate
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION refreshPreview
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Helper class used to store the state of schematic items that can be connected to other schematic item...
bool IsParallelTo(EDA_ANGLE aAngle) const
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
WX_INFOBAR * GetInfoBar()
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
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)
EDA_ITEM * GetParent() const
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
const VECTOR2I & GetTextPos() const
static TOOL_ACTION alignToGrid
static TOOL_ACTION highlightNet
static TOOL_ACTION clearSelection
Clears the current selection.
static TOOL_ACTION rotateCCW
static TOOL_ACTION restartMove
static TOOL_ACTION rotateCW
static TOOL_ACTION selectOnPCB
static const std::vector< KICAD_T > MovableItems
Implements an R-tree for fast spatial and type indexing of schematic items.
EE_TYPE Overlapping(const BOX2I &aRect) const
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
An interface for classes handling user events controlling the view behavior such as zooming,...
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
virtual void Revert() override
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SchematicCleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void SelectUnit(SCH_SYMBOL *aSymbol, int aUnit)
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
SCH_JUNCTION * AddJunction(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen, const VECTOR2I &aPos)
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetStoredPos(const VECTOR2I &aPos)
virtual bool CanConnect(const SCH_ITEM *aItem) const
void ClearFieldsAutoplaced()
void SetLayer(SCH_LAYER_ID aLayer)
Set the layer this item is on.
void SetConnectivityDirty(bool aDirty=true)
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
virtual bool IsMovableFromAnchorPoint() const
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
void SetLastResolvedState(const SCH_ITEM *aItem) override
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
void SetPosition(const VECTOR2I &aPosition) override
bool CanConnect(const SCH_ITEM *aItem) const override
Segment description base class to describe items which have 2 end points (track, wire,...
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
void StoreAngle()
Saves the current line angle.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
EDA_ANGLE Angle() const
Gets the angle between the start and end lines.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
void MoveEnd(const VECTOR2I &aMoveVector)
void SetLastResolvedState(const SCH_ITEM *aItem) override
void MoveStart(const VECTOR2I &aMoveVector)
void SetEndPoint(const VECTOR2I &aPosition)
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
bool IsExplicitJunctionNeeded(const VECTOR2I &aPosition) const
Indicates that a junction dot is necessary at the given location, and does not yet exist.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetSize(const VECTOR2I &aSize)
VECTOR2I GetPosition() const override
std::vector< SCH_SHEET_PIN * > & GetPins()
TRANSFORM & GetTransform()
VECTOR2I GetPosition() const override
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual void Add(EDA_ITEM *aItem)
const std::vector< EDA_ITEM * > GetItemsSortedByTypeAndXY(bool leftBeforeRight=true, bool topBeforeBottom=true) const
Returns a copy of this selection of items sorted by their X then Y position.
VECTOR2I GetReferencePoint() const
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
bool HasReferencePoint() const
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
static constexpr EDA_ANGLE & ANGLE_90
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_CHANGED
Item was edited, and modified.
#define IS_NEW
New item, just created.
#define SELECTED
Item was manually selected by the user.
#define SELECTED_BY_DRAG
Item was algorithmically selected as a dragged item.
#define IS_BROKEN
Is a segment just broken by BreakSegment.
#define STRUCT_DELETED
flag indication structures to be erased
#define ENDPOINT
ends. (Used to support dragging.)
#define IS_MOVING
Item being moved.
#define STARTPOINT
When a line is selected, these flags indicate which.
@ ID_POPUP_SCH_SELECT_UNIT
@ ID_POPUP_SCH_SELECT_UNIT_END
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
@ REPAINT
Item needs to be redrawn.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.