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;
400 catch(
const std::runtime_error& e )
402 wxCHECK_MSG(
false,
false, e.what() );
417 if( sel && !sel->
IsNew() )
451 bool unselect = selection.
IsHover();
454 std::vector<DANGLING_END_ITEM> internalPoints;
463 if( selection.
Empty() )
471 bool restore_state =
false;
496 bool placingNewItems = sch_item && sch_item->
IsNew();
504 internalPoints.clear();
511 if( !it->IsSelected() )
524 std::vector<SCH_ITEM*> stageTwo;
526 for(
EDA_ITEM* edaItem : selection )
529 std::vector<VECTOR2I> connections;
531 switch( item->
Type() )
537 stageTwo.emplace_back(item);
541 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
547 for(
const VECTOR2I& point : connections )
555 for(
const VECTOR2I& point : item->GetConnectionPoints() )
559 for(
EDA_ITEM* item : connectedDragItems )
567 for(
EDA_ITEM* edaItem : selection )
588 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
590 std::vector<DANGLING_END_ITEM> endPointsByType = internalPoints;
591 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
596 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( endPointsByType,
602 snapLayer =
grid.GetSelectionGrid( selection );
610 else if( item->GetParent() && item->GetParent()->IsSelected() )
622 schItem->SetStoredPos( schItem->GetPosition() );
631 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
633 else if( placingNewItems )
641 bool isPasted =
false;
647 if( item->GetParent() && item->GetParent()->IsSelected() )
653 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
661 selection.SetReferencePoint(
m_cursor );
678 selection.SetReferencePoint(
m_cursor );
698 snapLayer, selection );
708 std::vector<VECTOR2I> splitMoves;
739 for(
const VECTOR2I& splitDelta : splitMoves )
742 if( splitDelta ==
VECTOR2I( 0, 0 ) )
749 if( item->GetParent() && item->GetParent()->IsSelected() )
774 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
775 lineEnd.first->SetStartPoint(
pin->GetPosition() );
776 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
777 lineEnd.first->SetEndPoint(
pin->GetPosition() );
813 restore_state =
true;
889 }
while( ( evt =
Wait() ) );
897 selectionCopy.
Add( line );
900 selectionCopy.
Add( line );
905 newLine->ClearEditFlags();
912 oldLine->ClearEditFlags();
936 sch_item->SetConnectivityDirty(
true );
939 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
969 item->ClearEditFlags();
973 for(
EDA_ITEM* item : selectionCopy )
974 item->ClearEditFlags();
986 return !restore_state;
995 std::set<SCH_ITEM*> danglers;
997 std::function<void(
SCH_ITEM* )> changeHandler =
998 [&](
SCH_ITEM* aChangedItem ) ->
void
1005 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
1006 && !aChangedItem->IsSelected() )
1008 danglers.insert( aChangedItem );
1038 for(
SCH_ITEM* item : itemsOverlapping )
1040 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1043 foundJunction = item;
1049 if( foundSymbol && foundJunction )
1051 aList.push_back( foundSymbol );
1057 aList.push_back( foundJunction );
1064 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1067 switch(
test->Type() )
1083 if(
test->IsConnected( aPoint ) )
1084 aList.push_back(
test );
1090 aList.push_back(
test );
1103 if(
pin->IsConnected( aPoint ) )
1113 if(
test->IsConnected( aPoint ) )
1114 aList.push_back(
test );
1129 aList.push_back( label );
1141 if( line->
HitTest( aPoint, 1 ) )
1142 aList.push_back( label );
1159 std::vector<SCH_ITEM*> itemsConnectable;
1160 bool ptHasUnselectedJunction =
false;
1183 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1185 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1195 auto makeNewJunction =
1212 for(
SCH_ITEM* item : itemsOverlappingRTree )
1216 if( item == aSelectedItem || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1222 itemsConnectable.push_back( item );
1225 for(
SCH_ITEM* item : itemsConnectable )
1227 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1229 ptHasUnselectedJunction =
true;
1246 if( ptHasUnselectedJunction )
1266 aList.push_back( line );
1280 aList.push_back( line );
1285 switch( aSelectedItem->
Type() )
1299 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1302 aList.push_back( newWire );
1307 if( !line->
IsNew() )
1313 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1314 makeNewJunction( aCommit, line, aPoint );
1346 aList.push_back( label );
1349 info.attachedLine = line;
1361 if(
pin->IsConnected( aPoint ) )
1372 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1374 aList.push_back( newWire );
1383 if(
test->IsConnected( aPoint ) && !newWire )
1387 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1389 aList.push_back( newWire );
1398 aList.push_back(
test );
1434 aList.push_back( label );
1439 info.attachedLine = line;
1446 else if(
test->IsConnected( aPoint ) && !newWire )
1450 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1452 aList.push_back( newWire );
1478 if( line->
HitTest( point, 1 ) )
1481 aList.push_back(
test );
1484 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1487 if( ends[0] == point )
1511 switch( aItem->
Type() )
1553 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1554 pin->ConstrainOnEdge(
pin->GetStoredPos(), true );
1568 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1573 label->
Move( aDelta );
1580 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1613 if( !it->IsSelected() )
1616 if( !selection.
IsHover() && it->IsSelected() )
1619 it->SetStoredPos( it->GetPosition() );
1624 pin->SetStoredPos(
pin->GetPosition() );
1636 for(
int ii = 0; ii < 2; ++ii )
1643 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1649 for(
EDA_ITEM* dragItem : unique_items )
1651 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1654 doMoveItem( dragItem,
delta );
1664 doMoveItem( item,
delta );
1671 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1672 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1676 doMoveItem( sheet, tl_delta );
1687 if(
pin->GetSide() == SHEET_SIDE::TOP ||
pin->GetSide() == SHEET_SIDE::LEFT )
1688 newPos =
pin->GetPosition() + tl_delta;
1690 newPos =
pin->GetPosition() + br_delta;
1702 for(
EDA_ITEM* dragItem : drag_items )
1704 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1707 doMoveItem( dragItem,
delta );
1718 for(
const VECTOR2I& point : connections )
1721 std::map<VECTOR2I, int> shifts;
1725 for(
const VECTOR2I& conn : connections )
1727 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
1731 if( shifts[gridpt] > max_count )
1733 most_common = gridpt;
1734 max_count = shifts[most_common];
1738 if( most_common !=
VECTOR2I( 0, 0 ) )
1740 doMoveItem( item, most_common );
1742 for(
EDA_ITEM* dragItem : drag_items )
1744 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1747 doMoveItem( dragItem, most_common );
1760 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 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)
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
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_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.
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.