51#define QUIET_MODE true
56 m_inMoveTool( false ),
57 m_moveInProgress( false ),
106 bool foundAttachment =
false;
107 bool foundJunction =
false;
108 bool foundPin =
false;
113 foundAttachment =
true;
117 switch( cItem->Type() )
133 if( !foundLine && cLine->
GetLength() == 0 )
139 foundJunction =
true;
149 if( pair.first->IsConnected( selectedEnd ) )
169 bool preferOriginalLine =
false;
173 && line->GetLength() == 0
176 preferOriginalLine =
true;
182 else if( !foundLine && foundJunction && !foundPin )
185 foundLine =
new SCH_LINE( unselectedEnd, line->GetLayer() );
201 if( foundLine && !preferOriginalLine )
222 else if( foundLine->
GetEndPoint() == unselectedEnd )
223 foundLine->
MoveEnd( splitDelta );
279 line->MoveStart( splitDelta );
284 else if( line->GetLength() == 0 )
294 else if( foundAttachment && line->IsOrthogonal() )
301 unsigned int xMoveBit = splitDelta.
x != 0;
302 unsigned int yMoveBit = splitDelta.
y != 0;
303 int xLength = abs( unselectedEnd.
x - selectedEnd.
x );
304 int yLength = abs( unselectedEnd.
y - selectedEnd.
y );
305 int xMove = ( xLength - ( xBendCount * lineGrid.
x ) )
306 *
sign( selectedEnd.
x - unselectedEnd.
x );
307 int yMove = ( yLength - ( yBendCount * lineGrid.
y ) )
308 *
sign( selectedEnd.
y - unselectedEnd.
y );
328 xBendCount += yMoveBit;
329 yBendCount += xMoveBit;
334 line->MoveEnd(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
335 splitDelta.
y ? splitDelta.
y : yMove ) );
339 line->MoveStart(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
340 splitDelta.
y ? splitDelta.
y : yMove ) );
361 else if( !foundAttachment )
364 line->MoveEnd( splitDelta );
366 line->MoveStart( splitDelta );
378 bool isSlice =
false;
413 catch(
const std::runtime_error& e )
415 wxCHECK_MSG(
false,
false, e.what() );
430 if( sel && !sel->
IsNew() )
463 if( userSelection.
GetSize() == 1 )
483 bool unselect = selection.
IsHover();
486 std::vector<DANGLING_END_ITEM> internalPoints;
495 if( selection.
Empty() )
503 bool restore_state =
false;
528 bool placingNewItems = sch_item && sch_item->
IsNew();
536 internalPoints.clear();
543 if( !it->IsSelected() )
556 std::vector<SCH_ITEM*> stageTwo;
558 for(
EDA_ITEM* edaItem : selection )
561 std::vector<VECTOR2I> connections;
563 switch( item->
Type() )
569 stageTwo.emplace_back(item);
573 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
579 for(
const VECTOR2I& point : connections )
587 for(
const VECTOR2I& point : item->GetConnectionPoints() )
591 for(
EDA_ITEM* item : connectedDragItems )
599 for(
EDA_ITEM* edaItem : selection )
620 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
622 std::vector<DANGLING_END_ITEM> endPointsByType = internalPoints;
623 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
628 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( endPointsByType,
634 snapLayer =
grid.GetSelectionGrid( selection );
642 else if( item->GetParent() && item->GetParent()->IsSelected() )
654 schItem->SetStoredPos( schItem->GetPosition() );
663 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
665 else if( placingNewItems )
673 bool isPasted =
false;
679 if( item->GetParent() && item->GetParent()->IsSelected() )
685 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
693 selection.SetReferencePoint(
m_cursor );
710 selection.SetReferencePoint(
m_cursor );
730 snapLayer, selection );
740 std::vector<VECTOR2I> splitMoves;
771 for(
const VECTOR2I& splitDelta : splitMoves )
774 if( splitDelta ==
VECTOR2I( 0, 0 ) )
781 if( item->GetParent() && item->GetParent()->IsSelected() )
806 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
807 lineEnd.first->SetStartPoint(
pin->GetPosition() );
808 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
809 lineEnd.first->SetEndPoint(
pin->GetPosition() );
845 restore_state =
true;
933 }
while( ( evt =
Wait() ) );
941 selectionCopy.
Add( line );
944 selectionCopy.
Add( line );
949 newLine->ClearEditFlags();
956 oldLine->ClearEditFlags();
980 sch_item->SetConnectivityDirty(
true );
983 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
1013 item->ClearEditFlags();
1017 for(
EDA_ITEM* item : selectionCopy )
1018 item->ClearEditFlags();
1030 return !restore_state;
1039 std::set<SCH_ITEM*> danglers;
1041 std::function<void(
SCH_ITEM* )> changeHandler =
1042 [&](
SCH_ITEM* aChangedItem ) ->
void
1049 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
1050 && !aChangedItem->IsSelected() )
1052 danglers.insert( aChangedItem );
1082 for(
SCH_ITEM* item : itemsOverlapping )
1084 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1087 foundJunction = item;
1093 if( foundSymbol && foundJunction )
1095 aList.push_back( foundSymbol );
1101 aList.push_back( foundJunction );
1108 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1111 switch(
test->Type() )
1127 if(
test->IsConnected( aPoint ) )
1128 aList.push_back(
test );
1134 aList.push_back(
test );
1147 if(
pin->IsConnected( aPoint ) )
1149 if(
pin->IsSelected() )
1153 aList.push_back(
pin );
1163 if(
test->IsConnected( aPoint ) )
1164 aList.push_back(
test );
1179 aList.push_back( label );
1191 if( line->
HitTest( aPoint, 1 ) )
1192 aList.push_back( label );
1209 std::vector<SCH_ITEM*> itemsConnectable;
1210 bool ptHasUnselectedJunction =
false;
1233 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1235 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1245 auto makeNewJunction =
1262 for(
SCH_ITEM* item : itemsOverlappingRTree )
1271 &&
pin->CanConnect( aSelectedItem ) )
1273 itemsConnectable.push_back(
pin );
1282 if( item == aSelectedItem || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1288 itemsConnectable.push_back( item );
1291 for(
SCH_ITEM* item : itemsConnectable )
1293 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1295 ptHasUnselectedJunction =
true;
1312 if( ptHasUnselectedJunction )
1332 aList.push_back( line );
1346 aList.push_back( line );
1351 switch( aSelectedItem->
Type() )
1365 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1368 aList.push_back( newWire );
1373 if( !line->
IsNew() )
1379 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1380 makeNewJunction( aCommit, line, aPoint );
1412 aList.push_back( label );
1415 info.attachedLine = line;
1427 if(
pin->IsConnected( aPoint ) )
1438 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1440 aList.push_back( newWire );
1449 if(
test->IsConnected( aPoint ) && !newWire )
1453 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1455 aList.push_back( newWire );
1464 aList.push_back(
test );
1501 aList.push_back( label );
1506 info.attachedLine = line;
1513 else if(
test->IsConnected( aPoint ) && !newWire )
1517 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1519 aList.push_back( newWire );
1545 if( line->
HitTest( point, 1 ) )
1548 aList.push_back(
test );
1551 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1554 if( ends[0] == point )
1578 switch( aItem->
Type() )
1620 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1621 pin->ConstrainOnEdge(
pin->GetStoredPos(), true );
1635 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1640 label->
Move( aDelta );
1647 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1680 if( !it->IsSelected() )
1683 if( !selection.
IsHover() && it->IsSelected() )
1686 it->SetStoredPos( it->GetPosition() );
1691 pin->SetStoredPos(
pin->GetPosition() );
1703 for(
int ii = 0; ii < 2; ++ii )
1710 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1716 for(
EDA_ITEM* dragItem : unique_items )
1718 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1721 doMoveItem( dragItem,
delta );
1731 doMoveItem( item,
delta );
1738 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1739 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1743 doMoveItem( sheet, tl_delta );
1754 if(
pin->GetSide() == SHEET_SIDE::TOP ||
pin->GetSide() == SHEET_SIDE::LEFT )
1755 newPos =
pin->GetPosition() + tl_delta;
1757 newPos =
pin->GetPosition() + br_delta;
1769 for(
EDA_ITEM* dragItem : drag_items )
1771 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1774 doMoveItem( dragItem,
delta );
1785 for(
const VECTOR2I& point : connections )
1788 std::map<VECTOR2I, int> shifts;
1792 for(
const VECTOR2I& conn : connections )
1794 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
1798 if( shifts[gridpt] > max_count )
1800 most_common = gridpt;
1801 max_count = shifts[most_common];
1805 if( most_common !=
VECTOR2I( 0, 0 ) )
1807 doMoveItem( item, most_common );
1809 for(
EDA_ITEM* dragItem : drag_items )
1811 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1814 doMoveItem( dragItem, most_common );
1827 commit.
Push(
_(
"Align Items to Grid" ) );
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.
static void sort_dangling_end_items(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos)
Both contain the same information.
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,...
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
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...
virtual SETTINGS_MANAGER & GetSettingsManager() const
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 FlipBodyStyle(SCH_SYMBOL *aSymbol)
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,...
virtual bool CanConnect(const SCH_ITEM *aItem) const
void ClearFieldsAutoplaced()
void SetLayer(SCH_LAYER_ID aLayer)
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)
VECTOR2I GetReferencePoint() const
virtual unsigned int GetSize() const override
Return the number of stored items.
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
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.
bool HasReferencePoint() const
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
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_BASE
@ ID_POPUP_SCH_SELECT_ALT
@ ID_POPUP_SCH_SELECT_UNIT_END
@ REPAINT
Item needs to be redrawn.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
PGM_BASE & Pgm()
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.
constexpr int sign(T val)
VECTOR2< int32_t > VECTOR2I