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 Fixes: lp:1491052 * https://bugs.launchpad.net/kicad/+bug/1491052
This commit is contained in:
parent
b5ec5f9a73
commit
069448f20e
|
@ -127,9 +127,8 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
||||||
if( m_canvas->IsMouseCaptured() )
|
if( m_canvas->IsMouseCaptured() )
|
||||||
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
||||||
|
|
||||||
SaveCopyInUndoList( block->GetItems(), UR_MOVED, false, block->GetMoveVector() );
|
SaveCopyInUndoList( block->GetItems(), UR_CHANGED, false, block->GetMoveVector() );
|
||||||
MoveItemsInList( block->GetItems(), block->GetMoveVector() );
|
MoveItemsInList( block->GetItems(), block->GetMoveVector() );
|
||||||
block->ClearItemsList();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLOCK_DUPLICATE: /* Duplicate */
|
case BLOCK_DUPLICATE: /* Duplicate */
|
||||||
|
@ -141,8 +140,6 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
||||||
|
|
||||||
SaveCopyInUndoList( block->GetItems(),
|
SaveCopyInUndoList( block->GetItems(),
|
||||||
( block->GetCommand() == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW );
|
( block->GetCommand() == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW );
|
||||||
|
|
||||||
block->ClearItemsList();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLOCK_PASTE:
|
case BLOCK_PASTE:
|
||||||
|
@ -150,13 +147,15 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
||||||
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
||||||
|
|
||||||
PasteListOfItems( DC );
|
PasteListOfItems( DC );
|
||||||
block->ClearItemsList();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // others are handled by HandleBlockEnd()
|
default: // others are handled by HandleBlockEnd()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckJunctionsInList( block->GetItems(), true );
|
||||||
|
block->ClearItemsList();
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
|
|
||||||
// clear dome flags and pointers
|
// clear dome flags and pointers
|
||||||
|
@ -218,6 +217,8 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
||||||
SetCrossHairPosition( rotationPoint );
|
SetCrossHairPosition( rotationPoint );
|
||||||
SaveCopyInUndoList( block->GetItems(), UR_ROTATED, false, rotationPoint );
|
SaveCopyInUndoList( block->GetItems(), UR_ROTATED, false, rotationPoint );
|
||||||
RotateListOfItems( block->GetItems(), rotationPoint );
|
RotateListOfItems( block->GetItems(), rotationPoint );
|
||||||
|
CheckJunctionsInList( block->GetItems(), true );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +271,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
||||||
if( block->GetCount() )
|
if( block->GetCount() )
|
||||||
{
|
{
|
||||||
DeleteItemsInList( block->GetItems() );
|
DeleteItemsInList( block->GetItems() );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
block->ClearItemsList();
|
block->ClearItemsList();
|
||||||
|
@ -301,6 +303,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
||||||
copyBlockItems( block->GetItems() );
|
copyBlockItems( block->GetItems() );
|
||||||
MoveItemsInList( m_blockItems.GetItems(), move_vector );
|
MoveItemsInList( m_blockItems.GetItems(), move_vector );
|
||||||
DeleteItemsInList( block->GetItems() );
|
DeleteItemsInList( block->GetItems() );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +332,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
||||||
SetCrossHairPosition( mirrorPoint );
|
SetCrossHairPosition( mirrorPoint );
|
||||||
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, false, mirrorPoint );
|
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, false, mirrorPoint );
|
||||||
MirrorX( block->GetItems(), mirrorPoint );
|
MirrorX( block->GetItems(), mirrorPoint );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +352,7 @@ bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
||||||
SetCrossHairPosition( mirrorPoint );
|
SetCrossHairPosition( mirrorPoint );
|
||||||
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, false, mirrorPoint );
|
SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, false, mirrorPoint );
|
||||||
MirrorY( block->GetItems(), mirrorPoint );
|
MirrorY( block->GetItems(), mirrorPoint );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,81 +267,77 @@ 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()
|
void SCH_EDIT_FRAME::EndSegment()
|
||||||
{
|
{
|
||||||
SCH_SCREEN* screen = GetScreen();
|
SCH_SCREEN* screen = GetScreen();
|
||||||
SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
|
SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
|
||||||
|
PICKED_ITEMS_LIST itemList;
|
||||||
|
|
||||||
if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
|
if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Delete zero length segments and clear item flags.
|
// Remove segments backtracking over others
|
||||||
SCH_ITEM* item = s_wires.begin();
|
RemoveBacktracks( s_wires );
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( s_wires.GetCount() == 0 )
|
if( s_wires.GetCount() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Collect the possible connection points for the new lines
|
||||||
|
std::vector< wxPoint > connections;
|
||||||
|
std::vector< wxPoint > new_ends;
|
||||||
|
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;
|
||||||
|
|
||||||
|
wire->GetConnectionPoints( new_ends );
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
// Get the last non-null wire (this is the last created segment).
|
// Get the last non-null wire (this is the last created segment).
|
||||||
SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
|
SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
while( oldWires.GetCount() != 0 )
|
|
||||||
{
|
|
||||||
ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
|
|
||||||
oldItems.PushItem( picker );
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
|
|
||||||
|
|
||||||
// Remove segments backtracking over others
|
|
||||||
RemoveBacktracks( s_wires );
|
|
||||||
|
|
||||||
// Add the new wires
|
// Add the new wires
|
||||||
screen->Append( s_wires );
|
screen->Append( s_wires );
|
||||||
|
SaveCopyInUndoList(itemList, UR_NEW);
|
||||||
|
|
||||||
// Correct and remove segments that need to be merged.
|
// Correct and remove segments that need to be merged.
|
||||||
SchematicCleanUp();
|
SchematicCleanUp( true );
|
||||||
|
for( auto i : new_ends )
|
||||||
// A junction could be needed to connect the end point of the last created segment.
|
{
|
||||||
if( screen->IsJunctionNeeded( endpoint ) )
|
if( screen->IsJunctionNeeded( i, true ) )
|
||||||
screen->Append( AddJunction( endpoint ) );
|
AddJunction( i, true );
|
||||||
|
}
|
||||||
// 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();
|
|
||||||
|
|
||||||
|
screen->TestDanglingEnds();
|
||||||
|
screen->ClearDrawingState();
|
||||||
|
screen->SetCurItem( NULL );
|
||||||
|
m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,54 +437,100 @@ 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();
|
||||||
|
|
||||||
for( SCH_ITEM* item = GetScreen()->GetDrawItems() ; item; item = item->Next() )
|
auto remove_item = [ &itemList, screen ]( SCH_ITEM* aItem ) -> void
|
||||||
{
|
{
|
||||||
if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
|
aItem->SetFlags( STRUCT_DELETED );
|
||||||
|
itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
BreakSegmentsOnJunctions( true );
|
||||||
|
|
||||||
|
for( item = screen->GetDrawItems(); item; item = item->Next() )
|
||||||
|
{
|
||||||
|
if( ( item->Type() != SCH_LINE_T ) &&
|
||||||
|
( item->Type() != SCH_JUNCTION_T ) &&
|
||||||
|
( item->Type() != SCH_NO_CONNECT_T ))
|
||||||
continue;
|
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;
|
||||||
if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
|
}
|
||||||
|
// Remove zero-length lines
|
||||||
|
if( item->Type() == SCH_LINE_T
|
||||||
|
&& ( (SCH_LINE*) item )->IsNull() )
|
||||||
{
|
{
|
||||||
SCH_LINE* line = (SCH_LINE*) item;
|
remove_item( item );
|
||||||
|
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 ) )
|
|
||||||
{
|
|
||||||
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();
|
for( secondItem = item->Next(); secondItem; secondItem = secondItem->Next() )
|
||||||
|
{
|
||||||
|
if( item->Type() != secondItem->Type() || ( secondItem->GetFlags() & STRUCT_DELETED ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
return modified;
|
// Merge overlapping lines
|
||||||
|
if( item->Type() == SCH_LINE_T )
|
||||||
|
{
|
||||||
|
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 ) ) )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
|
||||||
|
return !!( itemList.GetCount() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE *aSegment, const wxPoint& aPoint, bool aAppend )
|
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE *aSegment, const wxPoint& aPoint, bool aAppend )
|
||||||
{
|
{
|
||||||
if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
|
if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
|
||||||
|
@ -552,20 +594,17 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( bool aAppend )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition,
|
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition, bool aAppend )
|
||||||
bool aPutInUndoList )
|
|
||||||
{
|
{
|
||||||
SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
|
SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
|
||||||
|
SCH_SCREEN* screen = GetScreen();
|
||||||
|
bool broken_segments = false;
|
||||||
|
|
||||||
SetRepeatItem( junction );
|
screen->Append( junction );
|
||||||
|
broken_segments = BreakSegments( aPosition, aAppend );
|
||||||
if( aPutInUndoList )
|
screen->TestDanglingEnds();
|
||||||
{
|
|
||||||
GetScreen()->Append( junction );
|
|
||||||
SaveCopyInUndoList( junction, UR_NEW );
|
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
SaveCopyInUndoList( junction, UR_NEW, broken_segments || aAppend );
|
||||||
|
|
||||||
return junction;
|
return junction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,19 +336,19 @@ public:
|
||||||
/**
|
/**
|
||||||
* Test if a junction is required for the items at \a aPosition on the screen.
|
* Test if a junction is required for the items at \a aPosition on the screen.
|
||||||
* <p>
|
* <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>
|
* <ul>
|
||||||
* <li>one wire midpoint, one or more wire endpoints and no junction.</li>
|
* <li>one wire midpoint and one or more wire endpoints;</li>
|
||||||
* <li>three or more wire endpoints and no junction.</li>
|
* <li>three or more wire endpoints;</li>
|
||||||
* <li>two wire midpoints and no junction</li>
|
* <li>one wire midpoint and a component pin;</li>
|
||||||
* <li>one wire midpoint, a component pin, and no junction.</li>
|
* <li>two or more wire endpoints and a component pin.</li>
|
||||||
* <li>three wire endpoints, a component pin, and no junction.</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
* @param aPosition The position to test.
|
* @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.
|
* @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.
|
* Test if \a aPosition is a connection point on \a aLayer.
|
||||||
|
|
|
@ -356,6 +356,11 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
}
|
}
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
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()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,6 +773,11 @@ bool SCH_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
|
||||||
|
|
||||||
UpdateFileHistory( fullFileName );
|
UpdateFileHistory( fullFileName );
|
||||||
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
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()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
||||||
|
|
||||||
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
|
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
|
||||||
|
|
|
@ -299,7 +299,13 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
||||||
screen->m_FirstRedraw = false;
|
screen->m_FirstRedraw = false;
|
||||||
SetCrossHairPosition( GetScrollCenterPosition() );
|
SetCrossHairPosition( GetScrollCenterPosition() );
|
||||||
m_canvas->MoveCursorToCrossHair();
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,6 +115,42 @@ 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
|
void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
|
||||||
{
|
{
|
||||||
PICKED_ITEMS_LIST itemsList;
|
PICKED_ITEMS_LIST itemsList;
|
||||||
|
|
|
@ -557,6 +557,7 @@ bool SCH_EDIT_FRAME::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
|
||||||
|
|
||||||
// Clean up wire ends
|
// Clean up wire ends
|
||||||
SchematicCleanUp();
|
SchematicCleanUp();
|
||||||
|
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
||||||
m_canvas->Refresh( true );
|
m_canvas->Refresh( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,8 @@ bool SCH_LINE::IsParallel( SCH_LINE* aLine )
|
||||||
return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
|
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
|
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.y < rhs.y;
|
||||||
return lhs.x < rhs.x;
|
return lhs.x < rhs.x;
|
||||||
};
|
};
|
||||||
|
wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, NULL,
|
||||||
wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
|
|
||||||
wxT( "Cannot test line segment for overlap." ) );
|
wxT( "Cannot test line segment for overlap." ) );
|
||||||
|
|
||||||
if( this == aLine || GetLayer() != aLine->GetLayer() )
|
if( this == aLine || GetLayer() != aLine->GetLayer() )
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
SCH_LINE leftmost = SCH_LINE( *aLine );
|
SCH_LINE leftmost = SCH_LINE( *aLine );
|
||||||
SCH_LINE rightmost = SCH_LINE( *this );
|
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 we end one before the beginning of the other, no overlap is possible
|
||||||
if( less( leftmost.m_end, other.m_start ) )
|
if( less( leftmost.m_end, other.m_start ) )
|
||||||
{
|
{
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for a common end:
|
// Search for a common end:
|
||||||
if( ( leftmost.m_start == other.m_start )
|
if( ( leftmost.m_start == other.m_start )
|
||||||
&& ( leftmost.m_end == other.m_end ) ) // Trivial case
|
&& ( leftmost.m_end == other.m_end ) ) // Trivial case
|
||||||
{
|
{
|
||||||
m_start = leftmost.m_start;
|
return new SCH_LINE( leftmost );
|
||||||
m_end = leftmost.m_end;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool colinear = false;
|
bool colinear = false;
|
||||||
|
@ -471,12 +469,11 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
|
||||||
// Make a new segment that merges the 2 segments
|
// Make a new segment that merges the 2 segments
|
||||||
if( colinear )
|
if( colinear )
|
||||||
{
|
{
|
||||||
m_start = leftmost.m_start;
|
leftmost.m_end = rightmost.m_end;
|
||||||
m_end = rightmost.m_end;
|
return new SCH_LINE( leftmost );
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -696,6 +693,7 @@ bool SCH_LINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
|
||||||
return rect.Intersects( m_start, m_end );
|
return rect.Intersects( m_start, m_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_LINE::SwapData( SCH_ITEM* aItem )
|
void SCH_LINE::SwapData( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
SCH_LINE* item = (SCH_LINE*) aItem;
|
SCH_LINE* item = (SCH_LINE*) aItem;
|
||||||
|
@ -711,6 +709,7 @@ void SCH_LINE::SwapData( SCH_ITEM* aItem )
|
||||||
std::swap( m_color, item->m_color );
|
std::swap( m_color, item->m_color );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_LINE::doIsConnected( const wxPoint& aPosition ) const
|
bool SCH_LINE::doIsConnected( const wxPoint& aPosition ) const
|
||||||
{
|
{
|
||||||
if( m_Layer != LAYER_WIRE && m_Layer != LAYER_BUS )
|
if( m_Layer != LAYER_WIRE && m_Layer != LAYER_BUS )
|
||||||
|
|
|
@ -133,14 +133,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* Check line against \a aLine to see if it overlaps and merge if it does.
|
* 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
|
* two lines overlap. This method is used to merge multiple line segments into a single
|
||||||
* line.
|
* line.
|
||||||
*
|
*
|
||||||
* @param aLine - Line to compare.
|
* @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
|
* Check if two lines are in the same quadrant as each other, using a reference point as
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#define EESCHEMA_FILE_STAMP "EESchema"
|
#define EESCHEMA_FILE_STAMP "EESchema"
|
||||||
|
|
||||||
|
@ -346,19 +347,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 ) )
|
bool has_line = false;
|
||||||
|
bool has_nonparallel = false;
|
||||||
|
int end_count = 0;
|
||||||
|
|
||||||
|
std::vector< SCH_LINE* > lines;
|
||||||
|
|
||||||
|
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
||||||
|
{
|
||||||
|
if( item->GetFlags() & STRUCT_DELETED )
|
||||||
|
continue;
|
||||||
|
if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( GetWire( aPosition, 0, EXCLUDE_END_POINTS_T ) )
|
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( GetWire( aPosition, 0, END_POINTS_ONLY_T ) )
|
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;
|
return true;
|
||||||
|
|
||||||
if( GetPin( aPosition, NULL, 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 true;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1098,30 +1139,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() )
|
for( item = m_drawList.begin(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
if( item->GetFlags() & STRUCT_DELETED )
|
if( item->GetFlags() & STRUCT_DELETED )
|
||||||
|
@ -1132,7 +1149,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis
|
||||||
|
|
||||||
tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
|
tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
|
||||||
|
|
||||||
if( tmp && tmp->GetFlags() & STRUCT_DELETED )
|
if( tmp && ( tmp->GetFlags() & STRUCT_DELETED ) )
|
||||||
{
|
{
|
||||||
item->SetFlags( STRUCT_DELETED );
|
item->SetFlags( STRUCT_DELETED );
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
case ID_POPUP_SCH_DELETE_CONNECTION:
|
case ID_POPUP_SCH_DELETE_CONNECTION:
|
||||||
m_canvas->MoveCursorToCrossHair();
|
m_canvas->MoveCursorToCrossHair();
|
||||||
DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
|
DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
|
||||||
|
SchematicCleanUp( true );
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
SetRepeatItem( NULL );
|
SetRepeatItem( NULL );
|
||||||
|
|
||||||
|
@ -214,6 +215,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DeleteItem( item );
|
DeleteItem( item );
|
||||||
|
SchematicCleanUp( true );
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
SetRepeatItem( NULL );
|
SetRepeatItem( NULL );
|
||||||
screen->TestDanglingEnds();
|
screen->TestDanglingEnds();
|
||||||
|
@ -630,6 +632,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
|
||||||
if( screen->GetConnection( pos, pickList, aFullConnection ) != 0 )
|
if( screen->GetConnection( pos, pickList, aFullConnection ) != 0 )
|
||||||
{
|
{
|
||||||
DeleteItemsInList( pickList );
|
DeleteItemsInList( pickList );
|
||||||
|
SchematicCleanUp( true );
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1443,7 +1443,16 @@ void SCH_EDIT_FRAME::addCurrentItemToList( bool aRedraw )
|
||||||
m_canvas->EndMouseCapture();
|
m_canvas->EndMouseCapture();
|
||||||
|
|
||||||
if( item->IsConnectable() )
|
if( item->IsConnectable() )
|
||||||
|
{
|
||||||
|
std::vector< wxPoint > pts;
|
||||||
|
item->GetConnectionPoints( pts );
|
||||||
|
for( auto i : pts )
|
||||||
|
{
|
||||||
|
if( screen->IsJunctionNeeded( i, true ) )
|
||||||
|
AddJunction( i, true );
|
||||||
|
}
|
||||||
screen->TestDanglingEnds();
|
screen->TestDanglingEnds();
|
||||||
|
}
|
||||||
|
|
||||||
if( aRedraw )
|
if( aRedraw )
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
|
|
|
@ -937,19 +937,25 @@ private:
|
||||||
SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aPutInUndoList = false );
|
SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aPutInUndoList = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function SaveWireImage
|
* Save a copy of the current wire image in the undo list.
|
||||||
* saves a copy of the current wire image in the undo list
|
|
||||||
*/
|
*/
|
||||||
void SaveWireImage();
|
void SaveWireImage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function SchematicCleanUp
|
* Collects a unique list of all possible connection points in the schematic.
|
||||||
* performs routine schematic cleaning including breaking wire and buses and
|
*
|
||||||
|
* @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.
|
* 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.
|
* @return True if any schematic clean up was performed.
|
||||||
*/
|
*/
|
||||||
bool SchematicCleanUp();
|
bool SchematicCleanUp( bool aAppend = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start moving \a aItem using the mouse.
|
* Start moving \a aItem using the mouse.
|
||||||
|
@ -1128,6 +1134,15 @@ public:
|
||||||
*/
|
*/
|
||||||
void DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend = false );
|
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; }
|
int GetLabelIncrement() const { return m_repeatLabelDelta; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue