kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #31856
Re: [PATCH] Eeschema automatic manage junctions
Updated patchset for this proposal, rebased to master. I've also updated
the commit messages to match the CHANGE:/NEW: format and added one new bug
from launchpad that this addresses.
-Seth
On Wed, Nov 8, 2017 at 3:59 AM, Nick Østergaard <oe.nick@xxxxxxxxx> wrote:
> For that specific issue with the junction drawing, there is a patch in the
> thread "[Kicad-developers] [PATCH] Draw junctions last"
>
> 2017-11-03 13:12 GMT+01:00 Jon Evans <jon@xxxxxxxxxxxxx>:
>
>> I looked at fixing this and some other related things, and decided to
>> just wait for the GAL port. There will need to be huge refactoring of the
>> eeschema draw code as part of that effort, so putting much effort into
>> making the wxDC drawing better seems not worth it.
>>
>> -Jon
>>
>> On Nov 3, 2017 00:08, "Kevin Cozens" <kevin@xxxxxxxxx> wrote:
>>
>> On 2017-11-02 06:31 PM, Seth Hillbrand wrote:
>>
>>> Please let me know if there are any additional issues or suggestions for
>>> improvement.
>>>
>>
>> How difficult would it be to have junctions draw last on schematics?
>> There is a minor negative visual effect when you have a component with one
>> end joined to a wire by a junction and you replace the component.
>>
>> When you replace the component the pin of the component is now seen
>> extending through the round disc of the junction to the center of the
>> junction. I prefer to always see just the full round disc of a junction
>> mark even if I have replaced a component since placing the junction.
>>
>> --
>> Cheers!
>>
>> Kevin.
>>
>> http://www.ve3syb.ca/ |"Nerds make the shiny things that
>> distract
>> Owner of Elecraft K2 #2172 | the mouth-breathers, and that's why
>> we're
>> | powerful!"
>> #include <disclaimer/favourite> | --Chris Hardwick
>>
>>
>> _______________________________________________
>> Mailing list: https://launchpad.net/~kicad-developers
>> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
>> Unsubscribe : https://launchpad.net/~kicad-developers
>> More help : https://help.launchpad.net/ListHelp
>>
>>
>>
>> _______________________________________________
>> Mailing list: https://launchpad.net/~kicad-developers
>> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
>> Unsubscribe : https://launchpad.net/~kicad-developers
>> More help : https://help.launchpad.net/ListHelp
>>
>>
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp
>
>
From b70ac1d34998ea04c62f4c74e8f7713fab24f601 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 12 Oct 2017 14:08:14 -0700
Subject: [PATCH 01/11] Optimize speed of TestSegmentHit
Improves speed of function by exiting on non-hits more quickly for
the majority of tests. Hits are also calculated slightly faster.
---
common/trigo.cpp | 172 +++++++++++++------------------------------------------
1 file changed, 39 insertions(+), 133 deletions(-)
diff --git a/common/trigo.cpp b/common/trigo.cpp
index 96dafa00e..5cf46d121 100644
--- a/common/trigo.cpp
+++ b/common/trigo.cpp
@@ -125,146 +125,52 @@ bool SegmentIntersectsSegment( const wxPoint &a_p1_l1, const wxPoint &a_p2_l1,
* aRefPoint = reference point to test
* aStart, aEnd are coordinates of end points segment
* aDist = maximum distance for hit
- * Note: for calculation time reasons, the distance between the ref point
- * and the segment is not always exactly calculated
- * (we only know if the actual dist is < aDist, not exactly know this dist.
- * Because many times we have horizontal or vertical segments,
- * a special calcultaion is made for them
- * Note: sometimes we need to calculate the distande between 2 points
- * A square root should be calculated.
- * However, because we just compare 2 distnaces, to avoid calculating square root,
- * the square of distances are compared.
+ *
*/
-static inline double square( int x ) // helper function to calculate x*x
-{
- return (double) x * x;
-}
bool TestSegmentHit( const wxPoint &aRefPoint, wxPoint aStart,
wxPoint aEnd, int aDist )
{
- // test for vertical or horizontal segment
- if( aEnd.x == aStart.x )
- {
- // vertical segment
- int ll = abs( aRefPoint.x - aStart.x );
-
- if( ll > aDist )
- return false;
-
- // To have only one case to examine, ensure aEnd.y > aStart.y
- if( aEnd.y < aStart.y )
- std::swap( aStart.y, aEnd.y );
-
- if( aRefPoint.y <= aEnd.y && aRefPoint.y >= aStart.y )
- return true;
-
- // there is a special case: x,y near an end point (distance < dist )
- // the distance should be carefully calculated
- if( (aStart.y - aRefPoint.y) < aDist )
- {
- double dd = square( aRefPoint.x - aStart.x) +
- square( aRefPoint.y - aStart.y );
- if( dd <= square( aDist ) )
- return true;
- }
-
- if( (aRefPoint.y - aEnd.y) < aDist )
- {
- double dd = square( aRefPoint.x - aEnd.x ) +
- square( aRefPoint.y - aEnd.y );
- if( dd <= square( aDist ) )
- return true;
- }
- }
- else if( aEnd.y == aStart.y )
- {
- // horizontal segment
- int ll = abs( aRefPoint.y - aStart.y );
-
- if( ll > aDist )
- return false;
-
- // To have only one case to examine, ensure xf > xi
- if( aEnd.x < aStart.x )
- std::swap( aStart.x, aEnd.x );
-
- if( aRefPoint.x <= aEnd.x && aRefPoint.x >= aStart.x )
- return true;
-
- // there is a special case: x,y near an end point (distance < dist )
- // the distance should be carefully calculated
- if( (aStart.x - aRefPoint.x) <= aDist )
- {
- double dd = square( aRefPoint.x - aStart.x ) +
- square( aRefPoint.y - aStart.y );
- if( dd <= square( aDist ) )
- return true;
- }
-
- if( (aRefPoint.x - aEnd.x) <= aDist )
- {
- double dd = square( aRefPoint.x - aEnd.x ) +
- square( aRefPoint.y - aEnd.y );
- if( dd <= square( aDist ) )
- return true;
- }
- }
- else
+ int xmin = aStart.x;
+ int xmax = aEnd.x;
+ int ymin = aStart.y;
+ int ymax = aEnd.y;
+ double dist_square = (double)aDist * aDist;
+ double length_square;
+ double delta_x, delta_y;
+
+ if( xmax < xmin )
+ std::swap( xmax, xmin );
+ if( ymax < ymin )
+ std::swap( ymax, ymin );
+
+ // First, check if we are outside of the bounding box
+ if ( ( ymin - aRefPoint.y > aDist ) || ( aRefPoint.y - ymax > aDist ) )
+ return false;
+ if ( ( xmin - aRefPoint.x > aDist ) || ( aRefPoint.x - xmax > aDist ) )
+ return false;
+
+ // Next, deal with a potential zero-length case
+ if ( aStart == aEnd )
{
- // oblique segment:
- // First, we need to calculate the distance between the point
- // and the line defined by aStart and aEnd
- // this dist should be < dist
- //
- // find a,slope such that aStart and aEnd lie on y = a + slope*x
- double slope = (double) (aEnd.y - aStart.y) / (aEnd.x - aStart.x);
- double a = (double) aStart.y - slope * aStart.x;
- // find c,orthoslope such that (x,y) lies on y = c + orthoslope*x,
- // where orthoslope=(-1/slope)
- // to calculate xp, yp = near point from aRefPoint
- // which is on the line defined by aStart, aEnd
- double orthoslope = -1.0 / slope;
- double c = (double) aRefPoint.y - orthoslope * aRefPoint.x;
- // find nearest point to (x,y) on line defined by aStart, aEnd
- double xp = (a - c) / (orthoslope - slope);
- double yp = a + slope * xp;
- // find distance to line, in fact the square of dist,
- // because we just know if it is > or < aDist
- double dd = square( aRefPoint.x - xp ) + square( aRefPoint.y - yp );
- double dist = square( aDist );
-
- if( dd > dist ) // this reference point is not a good candiadte.
- return false;
-
- // dd is < dist, therefore we should make a fine test
- if( fabs( slope ) > 0.7 )
- {
- // line segment more vertical than horizontal
- if( (aEnd.y > aStart.y && yp <= aEnd.y && yp >= aStart.y) ||
- (aEnd.y < aStart.y && yp >= aEnd.y && yp <= aStart.y) )
- return true;
- }
- else
- {
- // line segment more horizontal than vertical
- if( (aEnd.x > aStart.x && xp <= aEnd.x && xp >= aStart.x) ||
- (aEnd.x < aStart.x && xp >= aEnd.x && xp <= aStart.x) )
- return true;
- }
-
- // Here, the test point is still a good candidate,
- // however it is not "between" the end points of the segment.
- // It is "outside" the segment, but it could be near a segment end point
- // Therefore, we test the dist from the test point to each segment end point
- dd = square( aRefPoint.x - aEnd.x ) + square( aRefPoint.y - aEnd.y );
- if( dd <= dist )
- return true;
- dd = square( aRefPoint.x - aStart.x ) + square( aRefPoint.y - aStart.y );
- if( dd <= dist )
- return true;
+ delta_x = aStart.x - aRefPoint.x;
+ delta_y = aStart.y - aRefPoint.y;
+ return ( delta_x * delta_x + delta_y * delta_y <= dist_square);
}
- return false; // no hit
+ delta_x = aEnd.x - aStart.x;
+ delta_y = aEnd.y - aStart.y;
+ length_square = delta_x * delta_x + delta_y * delta_y;
+ // This is now the projection of the vector from start to reference onto the segment
+ double u = (aRefPoint.x - aStart.x) * delta_x + (aRefPoint.y - aStart.y) * delta_y;
+ // Sanity check that the projection is never negative or longer than the element itself
+ u = std::min( std::max( 0., u ), length_square );
+
+ // Calculate the x,y offsets by shifting from the start along the projection
+ // to the nearest point on the segment
+ double x = ( aStart.x - aRefPoint.x) + ( u * delta_x ) / length_square;
+ double y = ( aStart.y - aRefPoint.y) + ( u * delta_y ) / length_square;
+
+ return dist_square >= x * x + y * y;
}
--
2.11.0
From 6922daeea3cd1f5f904e3ab5d6e17ac64346ee87 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 26 Oct 2017 09:53:17 -0700
Subject: [PATCH 02/11] Eeschema: Simplify GetItem
Avoids calling HitTest on each item when it is not needed
---
eeschema/sch_screen.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
index edc90bc4b..cfdd458fc 100644
--- a/eeschema/sch_screen.cpp
+++ b/eeschema/sch_screen.cpp
@@ -216,9 +216,6 @@ SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T
{
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
{
- if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) )
- return item;
-
if( (aType == SCH_FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
{
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
@@ -240,7 +237,8 @@ SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T
if( label )
return (SCH_ITEM*) label;
}
- else if( (item->Type() == aType) && item->HitTest( aPosition, aAccuracy ) )
+ else if( ( ( item->Type() == aType ) || ( aType == NOT_USED ) )
+ && item->HitTest( aPosition, aAccuracy ) )
{
return item;
}
--
2.11.0
From 94eeddce2490fb9a5886cef909a390edaf46e05b Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 16 Nov 2017 12:36:09 -0800
Subject: [PATCH 03/11] Eeschema: Add 'append' option to undo/redo
NEW: Eeschema can add elements to previous undo commits
---
eeschema/block.cpp | 8 +++----
eeschema/edit_bitmap.cpp | 2 +-
eeschema/schematic_undo_redo.cpp | 47 +++++++++++++++++++++++++++++++++++-----
eeschema/schframe.h | 4 ++++
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/eeschema/block.cpp b/eeschema/block.cpp
index b6d0d7824..2d2af403f 100644
--- a/eeschema/block.cpp
+++ b/eeschema/block.cpp
@@ -127,7 +127,7 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
- SaveCopyInUndoList( block->GetItems(), UR_MOVED, block->GetMoveVector() );
+ SaveCopyInUndoList( block->GetItems(), UR_MOVED, false, block->GetMoveVector() );
MoveItemsInList( block->GetItems(), block->GetMoveVector() );
block->ClearItemsList();
break;
@@ -216,7 +216,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
wxPoint rotationPoint = block->Centre();
rotationPoint = GetNearestGridPosition( rotationPoint );
SetCrossHairPosition( rotationPoint );
- SaveCopyInUndoList( block->GetItems(), UR_ROTATED, rotationPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_ROTATED, false, rotationPoint );
RotateListOfItems( block->GetItems(), rotationPoint );
OnModify();
}
@@ -330,7 +330,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
wxPoint mirrorPoint = block->Centre();
mirrorPoint = GetNearestGridPosition( mirrorPoint );
SetCrossHairPosition( mirrorPoint );
- SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, mirrorPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, false, mirrorPoint );
MirrorX( block->GetItems(), mirrorPoint );
OnModify();
}
@@ -349,7 +349,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
wxPoint mirrorPoint = block->Centre();
mirrorPoint = GetNearestGridPosition( mirrorPoint );
SetCrossHairPosition( mirrorPoint );
- SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, mirrorPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, false, mirrorPoint );
MirrorY( block->GetItems(), mirrorPoint );
OnModify();
}
diff --git a/eeschema/edit_bitmap.cpp b/eeschema/edit_bitmap.cpp
index ad2a2b93a..d49efcda8 100644
--- a/eeschema/edit_bitmap.cpp
+++ b/eeschema/edit_bitmap.cpp
@@ -161,7 +161,7 @@ void SCH_EDIT_FRAME::MoveImage( SCH_BITMAP* aImageItem, wxDC* aDC )
void SCH_EDIT_FRAME::RotateImage( SCH_BITMAP* aItem )
{
if( aItem->GetFlags( ) == 0 )
- SaveCopyInUndoList( aItem, UR_ROTATED, aItem->GetPosition() );
+ SaveCopyInUndoList( aItem, UR_ROTATED, false, aItem->GetPosition() );
aItem->Rotate( aItem->GetPosition() );
OnModify();
diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp
index 09a83a6bc..75c1731eb 100644
--- a/eeschema/schematic_undo_redo.cpp
+++ b/eeschema/schematic_undo_redo.cpp
@@ -108,8 +108,11 @@
void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
UNDO_REDO_T aCommandType,
+ bool aAppend,
const wxPoint& aTransformPoint )
{
+ PICKED_ITEMS_LIST* commandToUndo = NULL;
+
/* Does not save a null item or a UR_WIRE_IMAGE command type. UR_WIRE_IMAGE commands
* are handled by the overloaded version of SaveCopyInUndoList that takes a reference
* to a PICKED_ITEMS_LIST.
@@ -117,8 +120,14 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
if( aItem == NULL || aCommandType == UR_WIRE_IMAGE )
return;
- PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
- commandToUndo->m_TransformPoint = aTransformPoint;
+ if( aAppend )
+ commandToUndo = GetScreen()->PopCommandFromUndoList();
+
+ if( !commandToUndo )
+ {
+ commandToUndo = new PICKED_ITEMS_LIST();
+ commandToUndo->m_TransformPoint = aTransformPoint;
+ }
ITEM_PICKER itemWrapper( aItem, aCommandType );
itemWrapper.SetFlags( aItem->GetFlags() );
@@ -160,15 +169,41 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
+ bool aAppend,
const wxPoint& aTransformPoint )
{
- PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
+ PICKED_ITEMS_LIST* commandToUndo = NULL;
+
+ if( !aItemsList.GetCount() )
+ return;
+
+ // Can't append a WIRE IMAGE, so fail to a new undo point
+ if( aAppend && ( aTypeCommand != UR_WIRE_IMAGE ) )
+ {
+ commandToUndo = GetScreen()->PopCommandFromUndoList();
+ if( commandToUndo && commandToUndo->m_Status == UR_WIRE_IMAGE )
+ {
+ GetScreen()->PushCommandToUndoList( commandToUndo );
+ commandToUndo = NULL;
+ }
+ }
- commandToUndo->m_TransformPoint = aTransformPoint;
- commandToUndo->m_Status = aTypeCommand;
+ if( !commandToUndo )
+ {
+ commandToUndo = new PICKED_ITEMS_LIST();
+ commandToUndo->m_TransformPoint = aTransformPoint;
+ commandToUndo->m_Status = aTypeCommand;
+ }
// Copy picker list:
- commandToUndo->CopyList( aItemsList );
+ if( !commandToUndo->GetCount() )
+ commandToUndo->CopyList( aItemsList );
+ else
+ {
+ // Unless we are appending, in which case, get the picker items
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ commandToUndo->PushItem( aItemsList.GetItemWrapper( ii) );
+ }
// Verify list, and creates data if needed
for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index e80e9bbeb..bd0f08a06 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -1161,11 +1161,13 @@ public:
*
* @param aItemToCopy = the schematic item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
UNDO_REDO_T aTypeCommand,
+ bool aAppend = false,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
@@ -1173,11 +1175,13 @@ public:
*
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
+ bool aAppend = false,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
private:
--
2.11.0
From f667cf229bf0b1ecc83c9add6abf471d5b683f4d Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 12 Oct 2017 16:41:25 -0700
Subject: [PATCH 04/11] Eeschema: Unify delete operations
CHANGE: DeleteItemsInList shares the code for DeleteItem.
CHANGE: DeleteItem removes junctions that are no longer needed.
---
eeschema/block.cpp | 4 +--
eeschema/operations_on_items_lists.cpp | 56 ++++++++++++++++++++++------------
eeschema/schedit.cpp | 2 +-
eeschema/schframe.h | 11 ++++++-
4 files changed, 49 insertions(+), 24 deletions(-)
diff --git a/eeschema/block.cpp b/eeschema/block.cpp
index 2d2af403f..f0a52f795 100644
--- a/eeschema/block.cpp
+++ b/eeschema/block.cpp
@@ -272,7 +272,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
if( block->GetCount() )
{
- DeleteItemsInList( m_canvas, block->GetItems() );
+ DeleteItemsInList( block->GetItems() );
OnModify();
}
block->ClearItemsList();
@@ -303,7 +303,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
wxPoint move_vector = -GetScreen()->m_BlockLocate.GetLastCursorPosition();
copyBlockItems( block->GetItems() );
MoveItemsInList( m_blockItems.GetItems(), move_vector );
- DeleteItemsInList( m_canvas, block->GetItems() );
+ DeleteItemsInList( block->GetItems() );
OnModify();
}
diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp
index a470c5d6f..ad8313d38 100644
--- a/eeschema/operations_on_items_lists.cpp
+++ b/eeschema/operations_on_items_lists.cpp
@@ -115,10 +115,8 @@ void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector
}
-void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList )
+void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
{
- SCH_SCREEN* screen = (SCH_SCREEN*) panel->GetScreen();
- SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) panel->GetParent();
PICKED_ITEMS_LIST itemsList;
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
@@ -126,46 +124,64 @@ void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList )
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
ITEM_PICKER itemWrapper( item, UR_DELETED );
- if( item->Type() == SCH_SHEET_PIN_T )
- {
- /* this item is depending on a sheet, and is not in global list */
- wxMessageBox( wxT( "DeleteItemsInList() err: unexpected SCH_SHEET_PIN_T" ) );
- }
- else
- {
- screen->Remove( item );
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue;
- /* Unlink the structure */
- itemsList.PushItem( itemWrapper );
- }
+ DeleteItem( item, aAppend );
+ aAppend = true;
}
- frame->SaveCopyInUndoList( itemsList, UR_DELETED );
+ GetScreen()->ClearDrawingState();
}
-void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem )
+void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem, bool aAppend )
{
wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item." ) );
+ wxCHECK_RET( !( aItem->GetFlags() & STRUCT_DELETED ),
+ wxT( "Cannot delete item that is already deleted." ) );
// Here, aItem is not null.
-
SCH_SCREEN* screen = GetScreen();
if( aItem->Type() == SCH_SHEET_PIN_T )
{
- // This iten is attached to a node, and is not accessible by the global list directly.
+ // This item is attached to a node, and is not accessible by the global list directly.
SCH_SHEET* sheet = (SCH_SHEET*) aItem->GetParent();
wxCHECK_RET( (sheet != NULL) && (sheet->Type() == SCH_SHEET_T),
wxT( "Sheet label has invalid parent item." ) );
- SaveCopyInUndoList( (SCH_ITEM*) sheet, UR_CHANGED );
+ SaveCopyInUndoList( (SCH_ITEM*) sheet, UR_CHANGED, aAppend );
sheet->RemovePin( (SCH_SHEET_PIN*) aItem );
m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
}
else
{
+ PICKED_ITEMS_LIST itemsList;
+ ITEM_PICKER picker( aItem, UR_DELETED );
+
+ aItem->SetFlags( STRUCT_DELETED );
+ itemsList.PushItem( picker );
screen->Remove( aItem );
- SaveCopyInUndoList( aItem, UR_DELETED );
+
+ if( aItem->IsConnectable() && aItem->Type() != SCH_JUNCTION_T )
+ {
+ std::vector< wxPoint > pts;
+ aItem->GetConnectionPoints( pts );
+ for( auto point : pts )
+ {
+ SCH_ITEM* junction;
+ if( !screen->IsJunctionNeeded( point )
+ && ( junction = screen->GetItem( point, 0, SCH_JUNCTION_T ) ) )
+ {
+ ITEM_PICKER picker_juction( junction, UR_DELETED );
+ junction->SetFlags( STRUCT_DELETED );
+ itemsList.PushItem( picker_juction );
+ screen->Remove( junction );
+ }
+ }
+ }
+
+ SaveCopyInUndoList( itemsList, UR_DELETED, aAppend );
m_canvas->RefreshDrawingRect( aItem->GetBoundingBox() );
}
}
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 102f1fcbe..80b17570c 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -648,7 +648,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
if( screen->GetConnection( pos, pickList, aFullConnection ) != 0 )
{
- DeleteItemsInList( m_canvas, pickList );
+ DeleteItemsInList( pickList );
OnModify();
}
}
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index bd0f08a06..1e3e46dd8 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -1073,7 +1073,16 @@ public:
*
* @param aItem The item to remove from the current screen.
*/
- void DeleteItem( SCH_ITEM* aItem );
+ void DeleteItem( SCH_ITEM* aItem, bool aAppend = false );
+
+ /**
+ * Removes all items (and unused junctions that connect to them) and saves
+ * each in the undo list
+ *
+ * @param aItemsList The list of items to delete
+ * @param aAppend True if we are updating a previous commit
+ */
+ void DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend = false );
int GetLabelIncrement() const { return m_repeatLabelDelta; }
--
2.11.0
From 60b34dcf264bc52ac9802686c5e08e5c92b63ec5 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Mon, 16 Oct 2017 14:38:57 -0700
Subject: [PATCH 05/11] Eeschema: Add two utility functions to sch_line
NEW: Add IsSameQuandrant and IsParallel functions
---
eeschema/sch_line.cpp | 36 ++++++++++++++++++++++++++++++++++++
eeschema/sch_line.h | 12 ++++++++++++
2 files changed, 48 insertions(+)
diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp
index 4e3246c2a..7a05fee98 100644
--- a/eeschema/sch_line.cpp
+++ b/eeschema/sch_line.cpp
@@ -352,6 +352,42 @@ void SCH_LINE::Rotate( wxPoint aPosition )
}
+bool SCH_LINE::IsSameQuadrant( SCH_LINE* aLine, const wxPoint& aPosition )
+{
+ wxPoint first;
+ wxPoint second;
+
+ if( m_start == aPosition )
+ first = m_end - aPosition;
+ else if( m_end == aPosition )
+ first = m_start - aPosition;
+ else
+ return false;
+
+ if( aLine->m_start == aPosition )
+ second = aLine->m_end - aPosition;
+ else if( aLine->m_end == aPosition )
+ second = aLine->m_start - aPosition;
+ else
+ return false;
+
+ return (std::signbit( first.x ) == std::signbit( second.x ) &&
+ std::signbit( first.y ) == std::signbit( second.y ) );
+}
+
+
+bool SCH_LINE::IsParallel( SCH_LINE* aLine )
+{
+ wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
+ wxT( "Cannot test line segment for overlap." ) );
+
+ wxPoint firstSeg = m_end - m_start;
+ wxPoint secondSeg = aLine->m_end - aLine->m_start;
+
+ // Use long long here to avoid overflow in calculations
+ return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
+}
+
bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
{
auto less = []( const wxPoint& lhs, const wxPoint& rhs ) -> bool
diff --git a/eeschema/sch_line.h b/eeschema/sch_line.h
index ac84a2a6c..6b7594c31 100644
--- a/eeschema/sch_line.h
+++ b/eeschema/sch_line.h
@@ -142,6 +142,18 @@ public:
*/
bool MergeOverlap( SCH_LINE* aLine );
+ /**
+ * Check if two lines are in the same quadrant as each other, using a reference point as
+ * the origin
+ *
+ * @param aLine - Line to compare
+ * @param aPosition - Point to reference against lines
+ * @return true if lines are mostly in different quadrants of aPosition, false otherwise
+ */
+ bool IsSameQuadrant( SCH_LINE* aLine, const wxPoint& aPosition );
+
+ bool IsParallel( SCH_LINE* aLine );
+
void GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList ) override;
bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList ) override;
--
2.11.0
From 0a25c3cc245ae565c6a6acbd8c96775cd135d854 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Fri, 20 Oct 2017 09:31:02 -0700
Subject: [PATCH 06/11] Eeschema: don't cleanup unseen schematics
Changes to the schematic shouldn't be made
where the user isn't looking. Removing the
cleanup in ERC and netlisting prevents
unintended consequences
CHANGE: ERC and Netlist calls do not modify schematic
---
eeschema/dialogs/dialog_erc.cpp | 9 ---------
eeschema/netlist.cpp | 4 ----
2 files changed, 13 deletions(-)
diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp
index 8e811a40d..47c9d686b 100644
--- a/eeschema/dialogs/dialog_erc.cpp
+++ b/eeschema/dialogs/dialog_erc.cpp
@@ -478,15 +478,6 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
// Erase all previous DRC markers.
screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC );
- for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
- {
- /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted
- * data problems.
- */
- if( screen->SchematicCleanUp() )
- screen->ClearUndoRedoList();
- }
-
/* Test duplicate sheet names inside a given sheet, one cannot have sheets with
* duplicate names (file names can be duplicated).
*/
diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp
index 6252f27c4..ef5d0a5f5 100644
--- a/eeschema/netlist.cpp
+++ b/eeschema/netlist.cpp
@@ -83,9 +83,6 @@ bool SCH_EDIT_FRAME::prepareForNetlist()
return false;
}
- // Cleanup the entire hierarchy
- schematic.SchematicCleanUp();
-
return true;
}
@@ -123,7 +120,6 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
schematic.UpdateSymbolLinks();
SCH_SHEET_LIST sheets( g_RootSheet );
sheets.AnnotatePowerSymbols();
- schematic.SchematicCleanUp();
}
std::unique_ptr<NETLIST_OBJECT_LIST> connectedItemsList( BuildNetListBase() );
--
2.11.0
From d33defbb89c8e98c05224755c59c30aec5b73672 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Tue, 31 Oct 2017 12:33:00 -0700
Subject: [PATCH 07/11] Eeschema: Remove zero-length wires in RemoveBacktracks
CHANGE: RemoveBacktracks call removes zero-length wires as well
---
eeschema/bus-wire-junction.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index 528d09d68..fa0175463 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -74,6 +74,12 @@ static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires )
SCH_LINE *line = static_cast<SCH_LINE*>( p );
p = line->Next();
+ if( line->IsNull() )
+ {
+ delete s_wires.Remove( line );
+ continue;
+ }
+
if( !last_lines.empty() )
{
SCH_LINE* last_line = last_lines[last_lines.size() - 1];
--
2.11.0
From 1e54a60adb7a9143f895786a5bf3df979f5a522b Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Wed, 25 Oct 2017 15:21:42 -0700
Subject: [PATCH 08/11] Eeschema: Moving SchematicCleanup to SCH_EDIT_FRAME
CHANGE: SchematicCleanup function moved from SCH_SCREEN to
SCH_EDIT_FRAME
---
eeschema/bus-wire-junction.cpp | 53 ++++++++++++++++++++++++++++++++++--
eeschema/class_sch_screen.h | 14 ----------
eeschema/hierarch.cpp | 2 +-
eeschema/project_rescue.cpp | 2 +-
eeschema/sch_screen.cpp | 62 ------------------------------------------
eeschema/schframe.cpp | 2 +-
eeschema/schframe.h | 10 +++++++
7 files changed, 64 insertions(+), 81 deletions(-)
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index fa0175463..410f830f6 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -330,7 +330,7 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
screen->Append( s_wires );
// Correct and remove segments that need to be merged.
- screen->SchematicCleanUp();
+ SchematicCleanUp();
// A junction could be needed to connect the end point of the last created segment.
if( screen->IsJunctionNeeded( endpoint ) )
@@ -417,6 +417,55 @@ void SCH_EDIT_FRAME::DeleteCurrentSegment( wxDC* DC )
}
+bool SCH_EDIT_FRAME::SchematicCleanUp()
+{
+ bool modified = false;
+
+ for( SCH_ITEM* item = GetScreen()->GetDrawItems() ; item; item = item->Next() )
+ {
+ if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
+ continue;
+
+ bool restart;
+
+ for( SCH_ITEM* testItem = item->Next(); testItem; testItem = restart ? GetScreen()->GetDrawItems() : testItem->Next() )
+ {
+ restart = false;
+
+ if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
+ {
+ SCH_LINE* line = (SCH_LINE*) item;
+
+ if( line->MergeOverlap( (SCH_LINE*) testItem ) )
+ {
+ // Keep the current flags, because the deleted segment can be flagged.
+ item->SetFlags( testItem->GetFlags() );
+ DeleteItem( testItem );
+ restart = true;
+ modified = true;
+ }
+ }
+ else if ( ( ( item->Type() == SCH_JUNCTION_T )
+ && ( testItem->Type() == SCH_JUNCTION_T ) ) && ( testItem != item ) )
+ {
+ if ( testItem->HitTest( item->GetPosition() ) )
+ {
+ // Keep the current flags, because the deleted segment can be flagged.
+ item->SetFlags( testItem->GetFlags() );
+ DeleteItem( testItem );
+ restart = true;
+ modified = true;
+ }
+ }
+ }
+ }
+
+ GetScreen()->TestDanglingEnds();
+
+ return modified;
+}
+
+
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
bool aPutInUndoList )
{
@@ -445,7 +494,7 @@ SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( wxDC* aDC, const wxPoint& aPositio
SetRepeatItem( no_connect );
GetScreen()->Append( no_connect );
- GetScreen()->SchematicCleanUp();
+ SchematicCleanUp();
OnModify();
m_canvas->Refresh();
SaveCopyInUndoList( no_connect, UR_NEW );
diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h
index 92c564d83..7bd647ff5 100644
--- a/eeschema/class_sch_screen.h
+++ b/eeschema/class_sch_screen.h
@@ -262,16 +262,7 @@ public:
bool CheckIfOnDrawList( SCH_ITEM* st );
/**
- * Perform routine schematic cleaning including breaking wire and buses and
- * deleting identical objects superimposed on top of each other.
- *
- * @return True if any schematic clean up was performed.
- */
- bool SchematicCleanUp();
-
- /**
* Test all of the connectable objects in the schematic for unused connection points.
- *
* @return True if any connection state changes were made.
*/
bool TestDanglingEnds();
@@ -542,11 +533,6 @@ public:
void ClearAnnotation();
/**
- * Merge and break wire segments in the entire schematic hierarchy.
- */
- void SchematicCleanUp();
-
- /**
* Test all sheet and component objects in the schematic for duplicate time stamps
* and replaces them as necessary.
* Time stamps must be unique in order for complex hierarchies know which components go
diff --git a/eeschema/hierarch.cpp b/eeschema/hierarch.cpp
index d66aa4ea9..c41c82164 100644
--- a/eeschema/hierarch.cpp
+++ b/eeschema/hierarch.cpp
@@ -299,7 +299,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
screen->m_FirstRedraw = false;
SetCrossHairPosition( GetScrollCenterPosition() );
m_canvas->MoveCursorToCrossHair();
- screen->SchematicCleanUp();
+ SchematicCleanUp();
}
else
{
diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp
index 0a482d1c7..5cd22e76a 100644
--- a/eeschema/project_rescue.cpp
+++ b/eeschema/project_rescue.cpp
@@ -554,7 +554,7 @@ bool SCH_EDIT_FRAME::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
viewer->ReCreateListLib();
// Clean up wire ends
- GetScreen()->SchematicCleanUp();
+ SchematicCleanUp();
m_canvas->Refresh( true );
OnModify();
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
index cfdd458fc..56e9c2413 100644
--- a/eeschema/sch_screen.cpp
+++ b/eeschema/sch_screen.cpp
@@ -433,55 +433,6 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
}
-bool SCH_SCREEN::SchematicCleanUp()
-{
- bool modified = false;
-
- for( SCH_ITEM* item = m_drawList.begin() ; item; item = item->Next() )
- {
- if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
- continue;
-
- bool restart;
-
- for( SCH_ITEM* testItem = item->Next(); testItem; testItem = restart ? m_drawList.begin() : testItem->Next() )
- {
- restart = false;
-
- if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
- {
- SCH_LINE* line = (SCH_LINE*) item;
-
- if( line->MergeOverlap( (SCH_LINE*) testItem ) )
- {
- // Keep the current flags, because the deleted segment can be flagged.
- item->SetFlags( testItem->GetFlags() );
- DeleteItem( testItem );
- restart = true;
- modified = true;
- }
- }
- else if ( ( ( item->Type() == SCH_JUNCTION_T )
- && ( testItem->Type() == SCH_JUNCTION_T ) ) && ( testItem != item ) )
- {
- if ( testItem->HitTest( item->GetPosition() ) )
- {
- // Keep the current flags, because the deleted segment can be flagged.
- item->SetFlags( testItem->GetFlags() );
- DeleteItem( testItem );
- restart = true;
- modified = true;
- }
- }
- }
- }
-
- TestDanglingEnds();
-
- return modified;
-}
-
-
void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
{
// Initialize or reinitialize the pointer to the LIB_PART for each component
@@ -1373,19 +1324,6 @@ void SCH_SCREENS::ClearAnnotation()
m_screens[i]->ClearAnnotation( NULL );
}
-
-void SCH_SCREENS::SchematicCleanUp()
-{
- for( size_t i = 0; i < m_screens.size(); i++ )
- {
- // if wire list has changed, delete the undo/redo list to avoid
- // pointer problems with deleted data.
- if( m_screens[i]->SchematicCleanUp() )
- m_screens[i]->ClearUndoRedoList();
- }
-}
-
-
int SCH_SCREENS::ReplaceDuplicateTimeStamps()
{
EDA_ITEMS items;
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index 0cc8f0d86..97f23a5be 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -1243,7 +1243,7 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
libeditFrame->LoadComponentAndSelectLib( id );
}
- GetScreen()->SchematicCleanUp();
+ SchematicCleanUp();
m_canvas->Refresh();
}
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index 1e3e46dd8..a583ab46f 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -909,6 +909,15 @@ private:
SCH_JUNCTION* AddJunction( wxDC* aDC, const wxPoint& aPosition, bool aPutInUndoList = false );
/**
+ * Function SchematicCleanUp
+ * performs routine schematic cleaning including breaking wire and buses and
+ * deleting identical objects superimposed on top of each other.
+ *
+ * @return True if any schematic clean up was performed.
+ */
+ bool SchematicCleanUp();
+
+ /**
* Start moving \a aItem using the mouse.
*
* @param aItem A pointer to an SCH_ITEM to move.
@@ -1072,6 +1081,7 @@ public:
* Remove \a aItem from the current screen and saves it in the undo list.
*
* @param aItem The item to remove from the current screen.
+ * @param aAppend True if we are updating a previous Undo state
*/
void DeleteItem( SCH_ITEM* aItem, bool aAppend = false );
--
2.11.0
From 699bf73a0c2efce95f75627aa27bfa55db4cfce5 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 16 Nov 2017 12:39:59 -0800
Subject: [PATCH 09/11] Eeschema: Removing DC dependencies
---
eeschema/bus-wire-junction.cpp | 16 ++++++----------
eeschema/onleftclick.cpp | 6 +++---
eeschema/schedit.cpp | 4 ++--
eeschema/schframe.h | 7 +++----
4 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index 410f830f6..ea215c302 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -248,7 +248,7 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
// Terminate the command if the end point is on a pin, junction, or another wire or bus.
if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
{
- EndSegment( DC );
+ EndSegment();
return;
}
@@ -267,7 +267,7 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
}
-void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
+void SCH_EDIT_FRAME::EndSegment()
{
SCH_SCREEN* screen = GetScreen();
SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
@@ -334,11 +334,11 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
// A junction could be needed to connect the end point of the last created segment.
if( screen->IsJunctionNeeded( endpoint ) )
- screen->Append( AddJunction( DC, endpoint ) );
+ screen->Append( AddJunction( endpoint ) );
// A junction could be needed to connect the start point of the set of new created wires
if( screen->IsJunctionNeeded( startPoint ) )
- screen->Append( AddJunction( DC, startPoint ) );
+ screen->Append( AddJunction( startPoint ) );
m_canvas->Refresh();
@@ -466,17 +466,13 @@ bool SCH_EDIT_FRAME::SchematicCleanUp()
}
-SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
+SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition,
bool aPutInUndoList )
{
SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
SetRepeatItem( junction );
- m_canvas->CrossHairOff( aDC ); // Erase schematic cursor
- junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
- m_canvas->CrossHairOn( aDC ); // Display schematic cursor
-
if( aPutInUndoList )
{
GetScreen()->Append( junction );
@@ -488,7 +484,7 @@ SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
}
-SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( wxDC* aDC, const wxPoint& aPosition )
+SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( const wxPoint& aPosition )
{
SCH_NO_CONNECT* no_connect = new SCH_NO_CONNECT( aPosition );
diff --git a/eeschema/onleftclick.cpp b/eeschema/onleftclick.cpp
index ed349001b..2cfc9e045 100644
--- a/eeschema/onleftclick.cpp
+++ b/eeschema/onleftclick.cpp
@@ -120,7 +120,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
{
if( GetScreen()->GetItem( gridPosition, 0, SCH_NO_CONNECT_T ) == NULL )
{
- SCH_NO_CONNECT* no_connect = AddNoConnect( aDC, gridPosition );
+ SCH_NO_CONNECT* no_connect = AddNoConnect( gridPosition );
SetRepeatItem( no_connect );
GetScreen()->SetCurItem( no_connect );
m_canvas->SetAutoPanRequest( true );
@@ -137,7 +137,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
{
if( GetScreen()->GetItem( gridPosition, 0, SCH_JUNCTION_T ) == NULL )
{
- SCH_JUNCTION* junction = AddJunction( aDC, gridPosition, true );
+ SCH_JUNCTION* junction = AddJunction( gridPosition );
SetRepeatItem( junction );
GetScreen()->SetCurItem( junction );
m_canvas->SetAutoPanRequest( true );
@@ -442,7 +442,7 @@ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
case ID_WIRE_BUTT:
case ID_LINE_COMMENT_BUTT:
if( item && item->IsNew() )
- EndSegment( aDC );
+ EndSegment();
break;
}
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 80b17570c..61d9bf6e8 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -169,7 +169,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_END_LINE:
m_canvas->MoveCursorToCrossHair();
- EndSegment( &dc );
+ EndSegment();
break;
case ID_POPUP_SCH_BEGIN_WIRE:
@@ -372,7 +372,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_ADD_JUNCTION:
m_canvas->MoveCursorToCrossHair();
- screen->SetCurItem( AddJunction( &dc, GetCrossHairPosition(), true ) );
+ screen->SetCurItem( AddJunction( GetCrossHairPosition() ) );
if( screen->TestDanglingEnds() )
m_canvas->Refresh();
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index a583ab46f..76013d54d 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -897,16 +897,15 @@ private:
/**
* Add no connect item to the current schematic sheet at \a aPosition.
*
- * @param aDC The device context to draw the no connect to.
* @param aPosition The position in logical (drawing) units to add the no connect.
* @return The no connect item added.
*/
- SCH_NO_CONNECT* AddNoConnect( wxDC* aDC, const wxPoint& aPosition );
+ SCH_NO_CONNECT* AddNoConnect( const wxPoint& aPosition );
/**
* Add a new junction at \a aPosition.
*/
- SCH_JUNCTION* AddJunction( wxDC* aDC, const wxPoint& aPosition, bool aPutInUndoList = false );
+ SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aPutInUndoList = false );
/**
* Function SchematicCleanUp
@@ -950,7 +949,7 @@ private:
/**
* Terminate a bus, wire, or line creation.
*/
- void EndSegment( wxDC* DC );
+ void EndSegment();
/**
* Erase the last segment at the current mouse position.
--
2.11.0
From c5275eb85b615d1cf49f899a7af1c2e595dee613 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 26 Oct 2017 08:25:47 -0700
Subject: [PATCH 10/11] Eeschema: Moving BreakSegment into SCH_EDIT_FRAME
BreakSegment now breaks a known segment and BreakSegments
breaks all segments. This allows functions to break a
segment without needing to iterate through the whole list.
CHANGE: BreakSegment breaks a single segment
NEW: BreakSegments function replaces previous BreakSegment
---
eeschema/block.cpp | 3 --
eeschema/bus-wire-junction.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++
eeschema/class_sch_screen.h | 17 ---------
eeschema/sch_screen.cpp | 59 -----------------------------
eeschema/schedit.cpp | 23 +----------
eeschema/schframe.h | 34 +++++++++++++++++
6 files changed, 122 insertions(+), 100 deletions(-)
diff --git a/eeschema/block.cpp b/eeschema/block.cpp
index f0a52f795..f4aa8517c 100644
--- a/eeschema/block.cpp
+++ b/eeschema/block.cpp
@@ -228,9 +228,6 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
case BLOCK_DRAG:
case BLOCK_DRAG_ITEM: // Drag from a drag command
- GetScreen()->BreakSegmentsOnJunctions();
- // fall through
-
case BLOCK_MOVE:
case BLOCK_DUPLICATE:
if( block->GetCommand() == BLOCK_DRAG_ITEM &&
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index ea215c302..96c054c81 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -417,6 +417,30 @@ void SCH_EDIT_FRAME::DeleteCurrentSegment( wxDC* DC )
}
+void SCH_EDIT_FRAME::SaveWireImage()
+{
+ DLIST< SCH_ITEM > oldWires;
+
+ oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor.
+ GetScreen()->ExtractWires( oldWires, true );
+
+ if( oldWires.GetCount() != 0 )
+ {
+ PICKED_ITEMS_LIST oldItems;
+
+ oldItems.m_Status = UR_WIRE_IMAGE;
+
+ while( oldWires.GetCount() != 0 )
+ {
+ ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
+ oldItems.PushItem( picker );
+ }
+
+ SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
+ }
+}
+
+
bool SCH_EDIT_FRAME::SchematicCleanUp()
{
bool modified = false;
@@ -465,6 +489,68 @@ bool SCH_EDIT_FRAME::SchematicCleanUp()
return modified;
}
+bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE *aSegment, const wxPoint& aPoint, bool aAppend )
+{
+ if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
+ || aSegment->IsEndPoint( aPoint ) )
+ return false;
+
+ SaveCopyInUndoList( aSegment, UR_CHANGED, aAppend );
+ SCH_LINE* newSegment = new SCH_LINE( *aSegment );
+ SaveCopyInUndoList( newSegment, UR_NEW, true );
+
+ newSegment->SetStartPoint( aPoint );
+ aSegment->SetEndPoint( aPoint );
+ GetScreen()->Append( newSegment );
+
+ return true;
+}
+
+
+bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, bool aAppend )
+{
+ bool brokenSegments = false;
+
+ for( SCH_ITEM* segment = GetScreen()->GetDrawItems(); segment; segment = segment->Next() )
+ {
+ if( ( segment->Type() != SCH_LINE_T ) || ( segment->GetLayer() == LAYER_NOTES ) )
+ continue;
+
+ brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint, aAppend || brokenSegments );
+ }
+
+ return brokenSegments;
+}
+
+
+bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions()
+{
+ bool brokenSegments = false;
+
+ for( SCH_ITEM* item = GetScreen()->GetDrawItems(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_JUNCTION_T )
+ {
+ SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
+
+ if( BreakSegments( junction->GetPosition(), brokenSegments ) )
+ brokenSegments = true;
+ }
+ else
+ {
+ SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
+ if( busEntry )
+ {
+ if( BreakSegments( busEntry->GetPosition(), brokenSegments )
+ || BreakSegments( busEntry->m_End(), brokenSegments ) )
+ brokenSegments = true;
+ }
+ }
+ }
+
+ return brokenSegments;
+}
+
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition,
bool aPutInUndoList )
diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h
index 7bd647ff5..dd11205e0 100644
--- a/eeschema/class_sch_screen.h
+++ b/eeschema/class_sch_screen.h
@@ -308,23 +308,6 @@ public:
*/
int GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aList, bool aFullConnection );
- /**
- * Checks every wire and bus for a intersection at \a aPoint and break into two segments
- * at \a aPoint if an intersection is found.
- *
- * @param aPoint Test this point for an intersection.
- * @return True if any wires or buses were broken.
- */
- bool BreakSegment( const wxPoint& aPoint );
-
- /**
- * Tests all junctions and bus entries in the schematic for intersections with wires and
- * buses and breaks any intersections into multiple segments.
- *
- * @return True if any wires or buses were broken.
- */
- bool BreakSegmentsOnJunctions();
-
/* full undo redo management : */
// use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
// use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
index 56e9c2413..d1004af73 100644
--- a/eeschema/sch_screen.cpp
+++ b/eeschema/sch_screen.cpp
@@ -843,64 +843,6 @@ bool SCH_SCREEN::TestDanglingEnds()
}
-bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
-{
- SCH_LINE* segment;
- SCH_LINE* newSegment;
- bool brokenSegments = false;
-
- for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
- {
- if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
- continue;
-
- segment = (SCH_LINE*) item;
-
- if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
- continue;
-
- // Break the segment at aPoint and create a new segment.
- newSegment = new SCH_LINE( *segment );
- newSegment->SetStartPoint( aPoint );
- segment->SetEndPoint( aPoint );
- m_drawList.Insert( newSegment, segment->Next() );
- item = newSegment;
- brokenSegments = true;
- }
-
- return brokenSegments;
-}
-
-
-bool SCH_SCREEN::BreakSegmentsOnJunctions()
-{
- bool brokenSegments = false;
-
- for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
- {
- if( item->Type() == SCH_JUNCTION_T )
- {
- SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
-
- if( BreakSegment( junction->GetPosition() ) )
- brokenSegments = true;
- }
- else
- {
- SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
- if( busEntry )
- {
- if( BreakSegment( busEntry->GetPosition() )
- || BreakSegment( busEntry->m_End() ) )
- brokenSegments = true;
- }
- }
- }
-
- return brokenSegments;
-}
-
-
int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList )
{
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
@@ -1045,7 +987,6 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis
// Clear flags member for all items.
ClearDrawingState();
- BreakSegmentsOnJunctions();
if( GetNode( aPosition, list ) == 0 )
return 0;
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 61d9bf6e8..37a9fd652 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -200,28 +200,9 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_BREAK_WIRE:
{
- DLIST< SCH_ITEM > oldWires;
-
- oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor.
+ SaveWireImage();
m_canvas->MoveCursorToCrossHair();
- screen->ExtractWires( oldWires, true );
- screen->BreakSegment( GetCrossHairPosition() );
-
- if( oldWires.GetCount() != 0 )
- {
- PICKED_ITEMS_LIST oldItems;
-
- oldItems.m_Status = UR_WIRE_IMAGE;
-
- while( oldWires.GetCount() != 0 )
- {
- ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
- oldItems.PushItem( picker );
- }
-
- SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
- }
-
+ BreakSegments( GetCrossHairPosition() );
if( screen->TestDanglingEnds() )
m_canvas->Refresh();
}
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index 76013d54d..2749944b9 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -466,6 +466,34 @@ public:
bool aWarpMouse );
/**
+ * Breaks a single segment into two at the specified point
+ *
+ * @param aSegment Line segment to break
+ * @param aPoint Point at which to break the segment
+ * @param aAppend Add the changes to the previous undo state
+ * @return True if any wires or buses were broken.
+ */
+ bool BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bool aAppend = false );
+
+ /**
+ * Checks every wire and bus for a intersection at \a aPoint and break into two segments
+ * at \a aPoint if an intersection is found.
+ *
+ * @param aPoint Test this point for an intersection.
+ * @param aAppend Add the changes to the previous undo state
+ * @return True if any wires or buses were broken.
+ */
+ bool BreakSegments( const wxPoint& aPoint, bool aAppend = false );
+
+ /**
+ * Tests all junctions and bus entries in the schematic for intersections with wires and
+ * buses and breaks any intersections into multiple segments.
+ *
+ * @return True if any wires or buses were broken.
+ */
+ bool BreakSegmentsOnJunctions();
+
+ /**
* Send a message to Pcbnew via a socket connection.
*
* Commands are:
@@ -908,6 +936,12 @@ private:
SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aPutInUndoList = false );
/**
+ * Function SaveWireImage
+ * saves a copy of the current wire image in the undo list
+ */
+ void SaveWireImage();
+
+ /**
* Function SchematicCleanUp
* performs routine schematic cleaning including breaking wire and buses and
* deleting identical objects superimposed on top of each other.
--
2.11.0
From b053fee2e6e6af2338c01e99dddfc38262210ba0 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 16 Nov 2017 12:58:30 -0800
Subject: [PATCH 11/11] Eeschema: Automatically manage junctions
CHANGE: eeschema automatically adds and removes junctions
when required by the schematic
Fixes: lp:593888
* https://bugs.launchpad.net/kicad/+bug/593888
Fixes: lp:1482111
* https://bugs.launchpad.net/kicad/+bug/1482111
Fixes: lp:1563153
* https://bugs.launchpad.net/kicad/+bug/1563153
Fixes: lp:1730219
* https://bugs.launchpad.net/kicad/+bug/1730219
---
eeschema/block.cpp | 13 +-
eeschema/bus-wire-junction.cpp | 220 +++++++++++++++++++--------------
eeschema/class_sch_screen.h | 14 +--
eeschema/files-io.cpp | 10 ++
eeschema/hierarch.cpp | 8 +-
eeschema/operations_on_items_lists.cpp | 40 ++++++
eeschema/project_rescue.cpp | 1 +
eeschema/sch_line.cpp | 21 ++--
eeschema/sch_line.h | 6 +-
eeschema/sch_screen.cpp | 82 +++++++-----
eeschema/schedit.cpp | 3 +
eeschema/schframe.cpp | 9 ++
eeschema/schframe.h | 25 +++-
13 files changed, 294 insertions(+), 158 deletions(-)
diff --git a/eeschema/block.cpp b/eeschema/block.cpp
index f4aa8517c..4d4ce9adc 100644
--- a/eeschema/block.cpp
+++ b/eeschema/block.cpp
@@ -129,7 +129,6 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
SaveCopyInUndoList( block->GetItems(), UR_MOVED, false, block->GetMoveVector() );
MoveItemsInList( block->GetItems(), block->GetMoveVector() );
- block->ClearItemsList();
break;
case BLOCK_DUPLICATE: /* Duplicate */
@@ -141,8 +140,6 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
SaveCopyInUndoList( block->GetItems(),
( block->GetCommand() == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW );
-
- block->ClearItemsList();
break;
case BLOCK_PASTE:
@@ -150,13 +147,15 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
PasteListOfItems( DC );
- block->ClearItemsList();
break;
default: // others are handled by HandleBlockEnd()
break;
}
+ CheckJunctionsInList( block->GetItems(), true );
+ block->ClearItemsList();
+ SchematicCleanUp( true );
OnModify();
// clear dome flags and pointers
@@ -218,6 +217,8 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
SetCrossHairPosition( rotationPoint );
SaveCopyInUndoList( block->GetItems(), UR_ROTATED, false, rotationPoint );
RotateListOfItems( block->GetItems(), rotationPoint );
+ CheckJunctionsInList( block->GetItems(), true );
+ SchematicCleanUp( true );
OnModify();
}
@@ -270,6 +271,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
if( block->GetCount() )
{
DeleteItemsInList( block->GetItems() );
+ SchematicCleanUp( true );
OnModify();
}
block->ClearItemsList();
@@ -301,6 +303,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
copyBlockItems( block->GetItems() );
MoveItemsInList( m_blockItems.GetItems(), move_vector );
DeleteItemsInList( block->GetItems() );
+ SchematicCleanUp( true );
OnModify();
}
@@ -329,6 +332,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
SetCrossHairPosition( mirrorPoint );
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, false, mirrorPoint );
MirrorX( block->GetItems(), mirrorPoint );
+ SchematicCleanUp( true );
OnModify();
}
@@ -348,6 +352,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
SetCrossHairPosition( mirrorPoint );
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, false, mirrorPoint );
MirrorY( block->GetItems(), mirrorPoint );
+ SchematicCleanUp( true );
OnModify();
}
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index 96c054c81..39e07956b 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -266,82 +266,76 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
}
}
+void SCH_EDIT_FRAME::GetSchematicConnections( std::vector< wxPoint >& aConnections )
+{
+ for( SCH_ITEM* item = GetScreen()->GetDrawItems(); item; item = item->Next() )
+ item->GetConnectionPoints( aConnections );
+
+ // We always have some overlapping connection points. Drop duplicates here
+ std::sort( aConnections.begin(), aConnections.end(),
+ []( wxPoint& a, wxPoint& b ) -> bool
+ { return a.x < b.x || (a.x == b.x && a.y < b.y); } );
+ aConnections.erase( unique( aConnections.begin(), aConnections.end() ), aConnections.end() );
+}
void SCH_EDIT_FRAME::EndSegment()
{
SCH_SCREEN* screen = GetScreen();
SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
+ PICKED_ITEMS_LIST itemList;
if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
return;
- // Delete zero length segments and clear item flags.
- SCH_ITEM* item = s_wires.begin();
-
- while( item )
- {
- item->ClearFlags();
-
- wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) );
-
- segment = (SCH_LINE*) item;
- item = item->Next();
-
- if( segment->IsNull() )
- delete s_wires.Remove( segment );
- }
+ // Remove segments backtracking over others
+ RemoveBacktracks( s_wires );
if( s_wires.GetCount() == 0 )
return;
- // Get the last non-null wire (this is the last created segment).
- SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
+ // Collect the possible connection points for the new lines
+ std::vector< wxPoint > connections;
+ std::vector< wxPoint > new_ends;
- screen->SetCurItem( NULL );
- m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
-
- // store the terminal point of this last segment: a junction could be needed
- // (the last wire could be merged/deleted/modified, and lost)
- wxPoint endpoint = segment->GetEndPoint();
-
- // store the starting point of this first segment: a junction could be needed
- SCH_LINE* firstsegment = (SCH_LINE*) s_wires.GetFirst();
- wxPoint startPoint = firstsegment->GetStartPoint();
+ GetSchematicConnections( connections );
+ // Check each new segment for possible junctions and add/split if needed
+ for( SCH_ITEM* wire = s_wires.GetFirst(); wire; wire=wire->Next() )
+ {
+ SCH_LINE* test_line = (SCH_LINE*) wire;
+ if( wire->GetFlags() & SKIP_STRUCT )
+ continue;
- // Save the old wires for the undo command
- DLIST< SCH_ITEM > oldWires; // stores here the old wires
- GetScreen()->ExtractWires( oldWires, true ); // Save them in oldWires list
- // Put the snap shot of the previous wire, buses, and junctions in the undo/redo list.
- PICKED_ITEMS_LIST oldItems;
- oldItems.m_Status = UR_WIRE_IMAGE;
+ wire->GetConnectionPoints( new_ends );
- while( oldWires.GetCount() != 0 )
- {
- ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
- oldItems.PushItem( picker );
+ for( auto i : connections )
+ {
+ if( IsPointOnSegment( test_line->GetStartPoint(), test_line->GetEndPoint(), i ) )
+ {
+ new_ends.push_back( i );
+ }
+ }
+ itemList.PushItem( ITEM_PICKER( wire, UR_NEW ) );
}
- SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
-
- // Remove segments backtracking over others
- RemoveBacktracks( s_wires );
+ // Get the last non-null wire (this is the last created segment).
+ SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
// Add the new wires
screen->Append( s_wires );
+ SaveCopyInUndoList(itemList, UR_NEW);
// Correct and remove segments that need to be merged.
- SchematicCleanUp();
-
- // A junction could be needed to connect the end point of the last created segment.
- if( screen->IsJunctionNeeded( endpoint ) )
- screen->Append( AddJunction( endpoint ) );
-
- // A junction could be needed to connect the start point of the set of new created wires
- if( screen->IsJunctionNeeded( startPoint ) )
- screen->Append( AddJunction( startPoint ) );
-
- m_canvas->Refresh();
+ SchematicCleanUp( true );
+ for( auto i : new_ends )
+ {
+ if( screen->IsJunctionNeeded( i, true ) )
+ AddJunction( i, true );
+ }
+ screen->TestDanglingEnds();
+ screen->ClearDrawingState();
+ screen->SetCurItem( NULL );
+ m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
OnModify();
}
@@ -441,52 +435,95 @@ void SCH_EDIT_FRAME::SaveWireImage()
}
-bool SCH_EDIT_FRAME::SchematicCleanUp()
+bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
{
- bool modified = false;
+ SCH_ITEM* item = NULL;
+ SCH_ITEM* secondItem = NULL;
+ PICKED_ITEMS_LIST itemList;
+ SCH_SCREEN* screen = GetScreen();
+
+ auto remove_item = [ &itemList, screen ]( SCH_ITEM* aItem ) -> void
+ {
+ aItem->SetFlags( STRUCT_DELETED );
+ itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) );
+ };
- for( SCH_ITEM* item = GetScreen()->GetDrawItems() ; item; item = item->Next() )
+ for( item = screen->GetDrawItems(); item; item = item->Next() )
{
- if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
+ if( ( item->Type() != SCH_LINE_T ) &&
+ ( item->Type() != SCH_JUNCTION_T ) &&
+ ( item->Type() != SCH_NO_CONNECT_T ))
continue;
- bool restart;
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue;
- for( SCH_ITEM* testItem = item->Next(); testItem; testItem = restart ? GetScreen()->GetDrawItems() : testItem->Next() )
+ // Remove unneeded junctions
+ if( ( item->Type() == SCH_JUNCTION_T )
+ && ( !screen->IsJunctionNeeded( item->GetPosition() ) ) )
{
- restart = false;
+ remove_item( item );
+ continue;
+ }
+ // Remove zero-length lines
+ if( item->Type() == SCH_LINE_T
+ && ( (SCH_LINE*) item )->IsNull() )
+ {
+ remove_item( item );
+ continue;
+ }
- if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
- {
- SCH_LINE* line = (SCH_LINE*) item;
+ for( secondItem = item->Next(); secondItem; secondItem = secondItem->Next() )
+ {
+ if( item->Type() != secondItem->Type() || ( secondItem->GetFlags() & STRUCT_DELETED ) )
+ continue;
- if( line->MergeOverlap( (SCH_LINE*) testItem ) )
- {
- // Keep the current flags, because the deleted segment can be flagged.
- item->SetFlags( testItem->GetFlags() );
- DeleteItem( testItem );
- restart = true;
- modified = true;
- }
- }
- else if ( ( ( item->Type() == SCH_JUNCTION_T )
- && ( testItem->Type() == SCH_JUNCTION_T ) ) && ( testItem != item ) )
+ // Merge overlapping lines
+ if( item->Type() == SCH_LINE_T )
{
- if ( testItem->HitTest( item->GetPosition() ) )
+ SCH_LINE* firstLine = (SCH_LINE*) item;
+ SCH_LINE* secondLine = (SCH_LINE*) secondItem;
+ SCH_LINE* line = NULL;
+ bool needed = false;
+
+ if( !secondLine->IsParallel( firstLine ) )
+ continue;
+
+ // Check if a junction needs to be kept
+ // This can only happen if:
+ // 1) the endpoints overlap,
+ // 2) the lines are not pointing in the same direction AND
+ // 3) IsJunction Needed is false
+ if( secondLine->IsEndPoint( firstLine->GetStartPoint() )
+ && !secondLine->IsSameQuadrant( firstLine, firstLine->GetStartPoint() ) )
+ needed = screen->IsJunctionNeeded( firstLine->GetStartPoint() );
+ else if( secondLine->IsEndPoint( firstLine->GetEndPoint() )
+ && !secondLine->IsSameQuadrant( firstLine, firstLine->GetEndPoint() ) )
+ needed = screen->IsJunctionNeeded( firstLine->GetEndPoint() );
+
+ if( !needed && ( line = (SCH_LINE*) secondLine->MergeOverlap( firstLine ) ) )
{
- // Keep the current flags, because the deleted segment can be flagged.
- item->SetFlags( testItem->GetFlags() );
- DeleteItem( testItem );
- restart = true;
- modified = true;
+ remove_item( item );
+ remove_item( secondItem );
+ itemList.PushItem( ITEM_PICKER( line, UR_NEW ) );
+ screen->Append( (SCH_ITEM*) line );
+ break;
}
}
+ // Remove duplicate junctions and no-connects
+ else if( secondItem->GetPosition() == item->GetPosition() )
+ remove_item( secondItem );
}
}
+ for( item = screen->GetDrawItems(); item; item = secondItem )
+ {
+ secondItem = item->Next();
+ if( item->GetFlags() & STRUCT_DELETED )
+ screen->Remove( item );
+ }
+ SaveCopyInUndoList( itemList, UR_CHANGED, aAppend );
- GetScreen()->TestDanglingEnds();
-
- return modified;
+ return !!( itemList.GetCount() );
}
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE *aSegment, const wxPoint& aPoint, bool aAppend )
@@ -552,20 +589,17 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions()
}
-SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition,
- bool aPutInUndoList )
+SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition, bool aAppend )
{
SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
+ SCH_SCREEN* screen = GetScreen();
+ bool broken_segments = false;
- SetRepeatItem( junction );
-
- if( aPutInUndoList )
- {
- GetScreen()->Append( junction );
- SaveCopyInUndoList( junction, UR_NEW );
- OnModify();
- }
-
+ screen->Append( junction );
+ broken_segments = BreakSegments( aPosition, aAppend );
+ screen->TestDanglingEnds();
+ OnModify();
+ SaveCopyInUndoList( junction, UR_NEW, broken_segments || aAppend );
return junction;
}
diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h
index dd11205e0..a90763f35 100644
--- a/eeschema/class_sch_screen.h
+++ b/eeschema/class_sch_screen.h
@@ -336,19 +336,19 @@ public:
/**
* Test if a junction is required for the items at \a aPosition on the screen.
* <p>
- * A junction is required at \a aPosition if the following criteria are satisfied:
+ * A junction is required at \a aPosition if one of the following criteria is satisfied:
* <ul>
- * <li>one wire midpoint, one or more wire endpoints and no junction.</li>
- * <li>three or more wire endpoints and no junction.</li>
- * <li>two wire midpoints and no junction</li>
- * <li>one wire midpoint, a component pin, and no junction.</li>
- * <li>three wire endpoints, a component pin, and no junction.</li>
+ * <li>one wire midpoint and one or more wire endpoints;</li>
+ * <li>three or more wire endpoints;</li>
+ * <li>one wire midpoint and a component pin;</li>
+ * <li>two or more wire endpoints and a component pin.</li>
* </ul>
* </p>
* @param aPosition The position to test.
+ * @param aNew Checks if a _new_ junction is needed, i.e. there isn't one already
* @return True if a junction is required at \a aPosition.
*/
- bool IsJunctionNeeded( const wxPoint& aPosition );
+ bool IsJunctionNeeded( const wxPoint& aPosition, bool aNew = false );
/**
* Test if \a aPosition is a connection point on \a aLayer.
diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp
index c6a38495d..e99b6c54d 100644
--- a/eeschema/files-io.cpp
+++ b/eeschema/files-io.cpp
@@ -360,6 +360,11 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
}
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
+
+ // Ensure the schematic is fully segmented on first display
+ BreakSegmentsOnJunctions();
+ SchematicCleanUp( true );
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
}
@@ -772,6 +777,11 @@ bool SCH_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
UpdateFileHistory( fullFileName );
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
+
+ // Ensure the schematic is fully segmented on first display
+ BreakSegmentsOnJunctions();
+ SchematicCleanUp( true );
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
diff --git a/eeschema/hierarch.cpp b/eeschema/hierarch.cpp
index c41c82164..c65f388c4 100644
--- a/eeschema/hierarch.cpp
+++ b/eeschema/hierarch.cpp
@@ -299,7 +299,13 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
screen->m_FirstRedraw = false;
SetCrossHairPosition( GetScrollCenterPosition() );
m_canvas->MoveCursorToCrossHair();
- SchematicCleanUp();
+
+ // Ensure the schematic is fully segmented on first display
+ BreakSegmentsOnJunctions();
+ SchematicCleanUp( true );
+ screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
+
+ screen->TestDanglingEnds();
}
else
{
diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp
index ad8313d38..d3ff28636 100644
--- a/eeschema/operations_on_items_lists.cpp
+++ b/eeschema/operations_on_items_lists.cpp
@@ -115,6 +115,46 @@ void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector
}
+void SCH_EDIT_FRAME::CheckJunctionsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
+{
+ std::vector< wxPoint > pts;
+ std::vector< wxPoint > connections;
+
+ GetSchematicConnections( connections );
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ item->GetConnectionPoints( pts );
+ if( item->Type() == SCH_LINE_T )
+ {
+ SCH_LINE* line = (SCH_LINE*) item;
+ for( auto i : connections )
+ if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), i ) )
+ pts.push_back( i );
+ }
+
+ }
+ // We always have some overlapping connection points. Drop duplicates here
+ std::sort( pts.begin(), pts.end(),
+ []( wxPoint& a, wxPoint& b ) -> bool
+ { return a.x < b.x || (a.x == b.x && a.y < b.y); } );
+ pts.erase( unique( pts.begin(), pts.end() ), pts.end() );
+
+ for( auto point : pts )
+ {
+ if( GetScreen()->IsJunctionNeeded( point, true ) )
+ {
+ AddJunction( point, aAppend );
+ aAppend = true;
+ }
+ }
+}
+
+/**
+ * Function DeleteItemsInList
+ * delete schematic items in aItemsList
+ * deleted items are put in undo list
+ */
void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
{
PICKED_ITEMS_LIST itemsList;
diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp
index 5cd22e76a..feb37e645 100644
--- a/eeschema/project_rescue.cpp
+++ b/eeschema/project_rescue.cpp
@@ -555,6 +555,7 @@ bool SCH_EDIT_FRAME::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
// Clean up wire ends
SchematicCleanUp();
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
m_canvas->Refresh( true );
OnModify();
diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp
index 7a05fee98..385858dad 100644
--- a/eeschema/sch_line.cpp
+++ b/eeschema/sch_line.cpp
@@ -388,7 +388,8 @@ bool SCH_LINE::IsParallel( SCH_LINE* aLine )
return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
}
-bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
+
+EDA_ITEM* SCH_LINE::MergeOverlap( SCH_LINE* aLine )
{
auto less = []( const wxPoint& lhs, const wxPoint& rhs ) -> bool
{
@@ -396,12 +397,11 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
return lhs.y < rhs.y;
return lhs.x < rhs.x;
};
-
- wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
+ wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, NULL,
wxT( "Cannot test line segment for overlap." ) );
if( this == aLine || GetLayer() != aLine->GetLayer() )
- return false;
+ return NULL;
SCH_LINE leftmost = SCH_LINE( *aLine );
SCH_LINE rightmost = SCH_LINE( *this );
@@ -428,16 +428,14 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
// If we end one before the beginning of the other, no overlap is possible
if( less( leftmost.m_end, other.m_start ) )
{
- return false;
+ return NULL;
}
// Search for a common end:
if( ( leftmost.m_start == other.m_start )
&& ( leftmost.m_end == other.m_end ) ) // Trivial case
{
- m_start = leftmost.m_start;
- m_end = leftmost.m_end;
- return true;
+ return new SCH_LINE( leftmost );
}
bool colinear = false;
@@ -471,12 +469,11 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
// Make a new segment that merges the 2 segments
if( colinear )
{
- m_start = leftmost.m_start;
- m_end = rightmost.m_end;
- return true;
+ leftmost.m_end = rightmost.m_end;
+ return new SCH_LINE( leftmost );
}
- return false;
+ return NULL;
}
diff --git a/eeschema/sch_line.h b/eeschema/sch_line.h
index 6b7594c31..e82d48268 100644
--- a/eeschema/sch_line.h
+++ b/eeschema/sch_line.h
@@ -133,14 +133,14 @@ public:
/**
* Check line against \a aLine to see if it overlaps and merge if it does.
*
- * This method will change the line to be equivalent of the line and \a aLine if the
+ * This method will return an equivalent of the union of line and \a aLine if the
* two lines overlap. This method is used to merge multiple line segments into a single
* line.
*
* @param aLine - Line to compare.
- * @return True if lines overlap and the line was merged with \a aLine.
+ * @return New line that combines the two or NULL on non-overlapping segments.
*/
- bool MergeOverlap( SCH_LINE* aLine );
+ EDA_ITEM* MergeOverlap( SCH_LINE* aLine );
/**
* Check if two lines are in the same quadrant as each other, using a reference point as
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
index d1004af73..f6d7ce434 100644
--- a/eeschema/sch_screen.cpp
+++ b/eeschema/sch_screen.cpp
@@ -55,6 +55,7 @@
#include <lib_pin.h>
#include <symbol_lib_table.h>
+#include <boost/foreach.hpp>
#define EESCHEMA_FILE_STAMP "EESchema"
@@ -344,20 +345,59 @@ void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
}
-bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition )
+bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew )
{
- if( GetItem( aPosition, 0, SCH_JUNCTION_T ) )
- return false;
+ bool has_line = false;
+ bool has_nonparallel = false;
+ int end_count = 0;
+
+ std::vector< SCH_LINE* > lines;
- if( GetWire( aPosition, 0, EXCLUDE_END_POINTS_T ) )
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
{
- if( GetWire( aPosition, 0, END_POINTS_ONLY_T ) )
- return true;
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue;
+ if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
+ return false;
- if( GetPin( aPosition, NULL, true ) )
- return true;
+ if( item->Type() != SCH_LINE_T )
+ continue;
+
+ if( item->GetLayer() != LAYER_WIRE )
+ continue;
+
+ if( item->HitTest( aPosition, 0 ) )
+ lines.push_back( (SCH_LINE*) item );
+ }
+
+ BOOST_FOREACH( SCH_LINE* line, lines)
+ {
+ if( !line->IsEndPoint( aPosition ) )
+ has_line = true;
+ else
+ end_count++;
+ BOOST_REVERSE_FOREACH( SCH_LINE* second_line, lines )
+ {
+ if( line == second_line )
+ break;
+ if( line->IsEndPoint( second_line->GetStartPoint() )
+ && line->IsEndPoint( second_line->GetEndPoint() ) )
+ end_count--;
+ if( !line->IsParallel( second_line ) )
+ has_nonparallel = true;
+ }
}
+ int has_pin = !!( GetPin( aPosition, NULL, true ) );
+
+ // If there is line intersecting a pin or non-parallel end
+ if( has_pin && ( has_line || end_count > 1 ) )
+ return true;
+ // If there is at least one segment that ends on a non-parallel line or
+ // junction of two other lines
+ if( has_nonparallel && (has_line || end_count > 2 ) )
+ return true;
+
return false;
}
@@ -1096,30 +1136,6 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis
}
}
- // Get redundant junctions (junctions which connect < 3 end wires
- // and no pin)
- for( item = m_drawList.begin(); item; item = item->Next() )
- {
- if( item->GetFlags() & STRUCT_DELETED )
- continue;
-
- if( !(item->GetFlags() & CANDIDATE) )
- continue;
-
- if( item->Type() != SCH_JUNCTION_T )
- continue;
-
- SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
-
- if( CountConnectedItems( junction->GetPosition(), false ) <= 2 )
- {
- item->SetFlags( STRUCT_DELETED );
-
- ITEM_PICKER picker( item, UR_DELETED );
- aList.PushItem( picker );
- }
- }
-
for( item = m_drawList.begin(); item; item = item->Next() )
{
if( item->GetFlags() & STRUCT_DELETED )
@@ -1130,7 +1146,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis
tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
- if( tmp && tmp->GetFlags() & STRUCT_DELETED )
+ if( tmp && ( tmp->GetFlags() & STRUCT_DELETED ) )
{
item->SetFlags( STRUCT_DELETED );
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 37a9fd652..b9dad1587 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -190,6 +190,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_DELETE_CONNECTION:
m_canvas->MoveCursorToCrossHair();
DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
+ SchematicCleanUp( true );
screen->SetCurItem( NULL );
SetRepeatItem( NULL );
@@ -214,6 +215,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
DeleteItem( item );
+ SchematicCleanUp( true );
screen->SetCurItem( NULL );
SetRepeatItem( NULL );
screen->TestDanglingEnds();
@@ -630,6 +632,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
if( screen->GetConnection( pos, pickList, aFullConnection ) != 0 )
{
DeleteItemsInList( pickList );
+ SchematicCleanUp( true );
OnModify();
}
}
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index 97f23a5be..f2a193ebd 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -1437,7 +1437,16 @@ void SCH_EDIT_FRAME::addCurrentItemToList( bool aRedraw )
m_canvas->EndMouseCapture();
if( item->IsConnectable() )
+ {
+ std::vector< wxPoint > pts;
+ item->GetConnectionPoints( pts );
+ for( auto i : pts )
+ {
+ if( screen->IsJunctionNeeded( i, true ) )
+ AddJunction( i, true );
+ }
screen->TestDanglingEnds();
+ }
if( aRedraw )
GetCanvas()->Refresh();
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index 2749944b9..ee5e2983d 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -936,19 +936,25 @@ private:
SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aPutInUndoList = false );
/**
- * Function SaveWireImage
- * saves a copy of the current wire image in the undo list
+ * Save a copy of the current wire image in the undo list.
*/
void SaveWireImage();
/**
- * Function SchematicCleanUp
- * performs routine schematic cleaning including breaking wire and buses and
+ * Collects a unique list of all possible connection points in the schematic.
+ *
+ * @param aConnections vector of connections
+ */
+ void GetSchematicConnections( std::vector< wxPoint >& aConnections );
+
+ /**
+ * Performs routine schematic cleaning including breaking wire and buses and
* deleting identical objects superimposed on top of each other.
*
+ * @param aAppend The changes to the schematic should be appended to the previous undo
* @return True if any schematic clean up was performed.
*/
- bool SchematicCleanUp();
+ bool SchematicCleanUp( bool aAppend = false );
/**
* Start moving \a aItem using the mouse.
@@ -1127,6 +1133,15 @@ public:
*/
void DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend = false );
+ /**
+ * Adds junctions if needed to each item in the list after they have been
+ * moved.
+ *
+ * @param aItemsList The list of items to check
+ * @param aAppend True if we are updating a previous commit
+ */
+ void CheckJunctionsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend = false );
+
int GetLabelIncrement() const { return m_repeatLabelDelta; }
private:
--
2.11.0
Follow ups
References
-
[PATCH] Eeschema automatic manage junctions
From: Seth Hillbrand, 2017-10-17
-
Re: [PATCH] Eeschema automatic manage junctions
From: Seth Hillbrand, 2017-10-28
-
Re: [PATCH] Eeschema automatic manage junctions
From: Nick Østergaard, 2017-10-28
-
Re: [PATCH] Eeschema automatic manage junctions
From: Seth Hillbrand, 2017-10-28
-
Re: [PATCH] Eeschema automatic manage junctions
From: Nick Østergaard, 2017-10-28
-
Re: [PATCH] Eeschema automatic manage junctions
From: Seth Hillbrand, 2017-10-29
-
Re: [PATCH] Eeschema automatic manage junctions
From: Seth Hillbrand, 2017-11-02
-
Re: [PATCH] Eeschema automatic manage junctions
From: Kevin Cozens, 2017-11-03
-
Re: [PATCH] Eeschema automatic manage junctions
From: Jon Evans, 2017-11-03
-
Re: [PATCH] Eeschema automatic manage junctions
From: Nick Østergaard, 2017-11-08