Upgrade many editing actions to SCHEMATIC_COMMIT.

This commit is contained in:
Jeff Young 2023-06-09 17:24:49 +01:00
parent 73b653c276
commit e698156975
28 changed files with 504 additions and 554 deletions

View File

@ -192,15 +192,15 @@ std::unordered_set<SCH_SYMBOL*> getInferredSymbols( const EE_SELECTION& aSelecti
}
void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
void SCH_EDIT_FRAME::AnnotateSymbols( SCHEMATIC_COMMIT* aCommit,
ANNOTATE_SCOPE_T aAnnotateScope,
ANNOTATE_ORDER_T aSortOption,
ANNOTATE_ALGO_T aAlgoOption,
bool aRecursive,
int aStartNumber,
bool aResetAnnotation,
bool aRepairTimestamps,
REPORTER& aReporter,
bool appendUndo )
REPORTER& aReporter )
{
EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
EE_SELECTION& selection = selTool->GetSelection();
@ -354,8 +354,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
SCH_SYMBOL* symbol = ref.GetSymbol();
SCH_SHEET_PATH* sheet = &ref.GetSheetPath();
SaveCopyInUndoList( sheet->LastScreen(), symbol, UNDO_REDO::CHANGED, appendUndo );
appendUndo = true;
aCommit->Modify( symbol, sheet->LastScreen() );
ref.Annotate();
KIID_PATH full_uuid = sheet->Path();

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2023 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,6 +31,7 @@
#include <sch_no_connect.h>
#include <sch_screen.h>
#include <sch_view.h>
#include <schematic_commit.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
#include <tools/ee_selection_tool.h>
@ -49,7 +50,8 @@ void SCH_EDIT_FRAME::TestDanglingEnds()
}
bool SCH_EDIT_FRAME::TrimWire( const VECTOR2I& aStart, const VECTOR2I& aEnd )
bool SCH_EDIT_FRAME::TrimWire( SCHEMATIC_COMMIT* aCommit, const VECTOR2I& aStart,
const VECTOR2I& aEnd )
{
if( aStart == aEnd )
return false;
@ -92,20 +94,20 @@ bool SCH_EDIT_FRAME::TrimWire( const VECTOR2I& aStart, const VECTOR2I& aEnd )
// Step 1: break the segment on one end.
// Ensure that *line points to the segment containing aEnd
SCH_LINE* new_line;
BreakSegment( line, aStart, &new_line );
BreakSegment( aCommit, line, aStart, &new_line, screen );
if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aEnd ) )
line = new_line;
// Step 2: break the remaining segment.
// Ensure that *line _also_ contains aStart. This is our overlapping segment
BreakSegment( line, aEnd, &new_line );
BreakSegment( aCommit, line, aEnd, &new_line, screen );
if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aStart ) )
line = new_line;
SaveCopyInUndoList( screen, line, UNDO_REDO::DELETED, true );
RemoveFromScreen( line, screen );
aCommit->Removed( line, screen );
return true;
}
@ -114,11 +116,9 @@ bool SCH_EDIT_FRAME::TrimWire( const VECTOR2I& aStart, const VECTOR2I& aEnd )
}
bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
void SCH_EDIT_FRAME::SchematicCleanUp( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen )
{
PICKED_ITEMS_LIST itemList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
std::vector<SCH_ITEM*> deletedItems;
std::vector<SCH_LINE*> lines;
std::vector<SCH_JUNCTION*> junctions;
std::vector<SCH_NO_CONNECT*> ncs;
@ -134,12 +134,16 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
if( !( aItem->GetFlags() & STRUCT_DELETED ) )
{
aItem->SetFlags( STRUCT_DELETED );
itemList.PushItem( ITEM_PICKER( aScreen, aItem, UNDO_REDO::DELETED ) );
deletedItems.push_back( aItem );
if( aItem->IsSelected() )
selectionTool->RemoveItemFromSel( aItem, true /*quiet mode*/ );
RemoveFromScreen( aItem, aScreen );
aCommit->Removed( aItem, aScreen );
}
};
BreakSegmentsOnJunctions( aScreen );
BreakSegmentsOnJunctions( aCommit, aScreen );
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
{
@ -150,9 +154,7 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
}
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_NO_CONNECT_T ) )
{
ncs.push_back( static_cast<SCH_NO_CONNECT*>( item ) );
}
alg::for_all_pairs( junctions.begin(), junctions.end(),
[&]( SCH_JUNCTION* aFirst, SCH_JUNCTION* aSecond )
@ -237,9 +239,9 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
{
remove_item( firstLine );
remove_item( secondLine );
itemList.PushItem( ITEM_PICKER( aScreen, mergedLine, UNDO_REDO::NEWITEM ) );
AddToScreen( mergedLine, aScreen );
aCommit->Added( mergedLine, aScreen );
if( firstLine->IsSelected() || secondLine->IsSelected() )
selectionTool->AddItemToSel( mergedLine, true /*quiet mode*/ );
@ -249,55 +251,38 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
}
}
}
for( SCH_ITEM* item : deletedItems )
{
if( item->IsSelected() )
selectionTool->RemoveItemFromSel( item, true /*quiet mode*/ );
RemoveFromScreen( item, aScreen );
}
if( itemList.GetCount() )
SaveCopyInUndoList( itemList, UNDO_REDO::DELETED, true );
return itemList.GetCount() > 0;
}
void SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const VECTOR2I& aPoint,
SCH_LINE** aNewSegment, SCH_SCREEN* aScreen )
void SCH_EDIT_FRAME::BreakSegment( SCHEMATIC_COMMIT* aCommit, SCH_LINE* aSegment,
const VECTOR2I& aPoint, SCH_LINE** aNewSegment,
SCH_SCREEN* aScreen )
{
if( aScreen == nullptr )
aScreen = GetScreen();
// Save the copy of aSegment before breaking it
SaveCopyInUndoList( aScreen, aSegment, UNDO_REDO::CHANGED, true );
aCommit->Modify( aSegment, aScreen );
SCH_LINE* newSegment = aSegment->BreakAt( aPoint );
aSegment->SetFlags( IS_CHANGED | IS_BROKEN );
newSegment->SetFlags( IS_NEW | IS_BROKEN );
AddToScreen( newSegment, aScreen );
SaveCopyInUndoList( aScreen, newSegment, UNDO_REDO::NEWITEM, true );
aCommit->Added( newSegment, aScreen );
UpdateItem( aSegment, false, true );
if( aNewSegment )
*aNewSegment = newSegment;
*aNewSegment = newSegment;
}
bool SCH_EDIT_FRAME::BreakSegments( const VECTOR2I& aPoint, SCH_SCREEN* aScreen )
bool SCH_EDIT_FRAME::BreakSegments( SCHEMATIC_COMMIT* aCommit, const VECTOR2I& aPoint,
SCH_SCREEN* aScreen )
{
if( aScreen == nullptr )
aScreen = GetScreen();
bool brokenSegments = false;
bool brokenSegments = false;
SCH_LINE* new_line;
for( SCH_LINE* wire : aScreen->GetBusesAndWires( aPoint, true ) )
{
BreakSegment( wire, aPoint, nullptr, aScreen );
BreakSegment( aCommit, wire, aPoint, &new_line, aScreen );
brokenSegments = true;
}
@ -305,11 +290,8 @@ bool SCH_EDIT_FRAME::BreakSegments( const VECTOR2I& aPoint, SCH_SCREEN* aScreen
}
bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( SCH_SCREEN* aScreen )
bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen )
{
if( aScreen == nullptr )
aScreen = GetScreen();
bool brokenSegments = false;
std::set<VECTOR2I> point_set;
@ -326,7 +308,7 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( SCH_SCREEN* aScreen )
for( const VECTOR2I& pt : point_set )
{
BreakSegments( pt, aScreen );
BreakSegments( aCommit, pt, aScreen );
brokenSegments = true;
}
@ -334,21 +316,15 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( SCH_SCREEN* aScreen )
}
void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
void SCH_EDIT_FRAME::DeleteJunction( SCHEMATIC_COMMIT* aCommit, SCH_ITEM* aJunction )
{
SCH_SCREEN* screen = GetScreen();
PICKED_ITEMS_LIST undoList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
auto remove_item =
[&]( SCH_ITEM* aItem ) -> void
{
aItem->SetFlags( STRUCT_DELETED );
undoList.PushItem( ITEM_PICKER( screen, aItem, UNDO_REDO::DELETED ) );
};
remove_item( aJunction );
aJunction->SetFlags( STRUCT_DELETED );
RemoveFromScreen( aJunction, screen );
aCommit->Removed( aJunction, screen );
/// Note that std::list or similar is required here as we may insert values in the
/// loop below. This will invalidate iterators in a std::vector or std::deque
@ -380,27 +356,25 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
&& firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
{
remove_item( firstLine );
firstLine->SetFlags( STRUCT_DELETED );
return;
}
// Try to merge the remaining lines
if( SCH_LINE* line = secondLine->MergeOverlap( screen, firstLine, false ) )
if( SCH_LINE* new_line = secondLine->MergeOverlap( screen, firstLine, false ) )
{
remove_item( firstLine );
remove_item( secondLine );
undoList.PushItem( ITEM_PICKER( screen, line, UNDO_REDO::NEWITEM ) );
AddToScreen( line, screen );
firstLine->SetFlags( STRUCT_DELETED );
secondLine->SetFlags( STRUCT_DELETED );
AddToScreen( new_line, screen );
aCommit->Added( new_line, screen );
if( line->IsSelected() )
selectionTool->AddItemToSel( line, true /*quiet mode*/ );
if( new_line->IsSelected() )
selectionTool->AddItemToSel( new_line, true /*quiet mode*/ );
lines.push_back( line );
lines.push_back( new_line );
}
} );
SaveCopyInUndoList( undoList, UNDO_REDO::DELETED, aAppend );
for( SCH_LINE* line : lines )
{
if( line->GetEditFlags() & STRUCT_DELETED )
@ -409,32 +383,21 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
selectionTool->RemoveItemFromSel( line, true /*quiet mode*/ );
RemoveFromScreen( line, screen );
aCommit->Removed( line, screen );
}
}
}
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( SCH_SCREEN* aScreen, const VECTOR2I& aPos,
bool aUndoAppend, bool aFinal )
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen,
const VECTOR2I& aPos )
{
SCH_JUNCTION* junction = new SCH_JUNCTION( aPos );
AddToScreen( junction, aScreen );
SaveCopyInUndoList( aScreen, junction, UNDO_REDO::NEWITEM, aUndoAppend );
BreakSegments( aPos );
aCommit->Added( junction, aScreen );
if( aFinal )
{
m_toolManager->PostEvent( EVENTS::SelectedItemsModified );
TestDanglingEnds();
OnModify();
KIGFX::SCH_VIEW* view = GetCanvas()->GetView();
view->ClearPreview();
view->ShowPreview( false );
view->ClearHiddenFlags();
}
BreakSegments( aCommit, aPos, aScreen );
return junction;
}

View File

@ -907,7 +907,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
}
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
RecalculateConnections( GLOBAL_CLEANUP );
RecalculateConnections( nullptr, GLOBAL_CLEANUP );
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
STRING_FORMATTER formatter;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2017 jean-pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -24,14 +24,13 @@
#include <sch_edit_frame.h>
#include <base_units.h>
#include <bitmaps.h>
#include <confirm.h>
#include <dialog_annotate_base.h>
#include <eeschema_settings.h>
#include <kiface_base.h>
#include <widgets/wx_html_report_panel.h>
#include <schematic.h>
#include <schematic_commit.h>
// A window name for the annotate dialog to retrieve is if not destroyed
#define DLG_WINDOW_NAME "DialogAnnotateWindowName"
@ -215,19 +214,21 @@ void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event )
void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
{
SCHEMATIC_COMMIT commit( m_Parent );
m_MessageWindow->Clear();
REPORTER& reporter = m_MessageWindow->Reporter();
m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message
m_Parent->AnnotateSymbols( GetScope(), GetSortOrder(), GetAnnotateAlgo(), GetRecursive(),
GetStartNumber(), GetResetItems(), true, reporter );
m_Parent->AnnotateSymbols( &commit, GetScope(), GetSortOrder(), GetAnnotateAlgo(),
GetRecursive(), GetStartNumber(), GetResetItems(), true, reporter );
commit.Push( _( "Annotate" ) );
m_MessageWindow->Flush( true ); // Now update to show all messages
m_Parent->GetCanvas()->Refresh();
m_btnClear->Enable();
m_sdbSizer1Cancel->SetDefault();
// Don't close dialog if there are things the user needs to address

View File

@ -495,9 +495,9 @@ void DIALOG_ERC::testErc()
// If we are using the new connectivity, make sure that we do a full-rebuild
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
m_parent->RecalculateConnections( GLOBAL_CLEANUP );
m_parent->RecalculateConnections( nullptr, GLOBAL_CLEANUP );
else
m_parent->RecalculateConnections( NO_CLEANUP );
m_parent->RecalculateConnections( nullptr, NO_CLEANUP );
sch->ConnectionGraph()->RunERC();

View File

@ -21,7 +21,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <connection_graph.h>
#include <dialog_global_edit_text_and_graphics_base.h>
#include <string_utils.h>
#include <sch_symbol.h>
@ -33,7 +32,7 @@
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <advanced_config.h>
#include <schematic_commit.h>
#include <tool/tool_manager.h>
#include <tools/ee_selection_tool.h>
#include <tools/sch_edit_tool.h>

View File

@ -36,7 +36,7 @@ DIALOG_SHAPE_PROPERTIES::DIALOG_SHAPE_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_S
m_shape( aShape ),
m_borderWidth( aParent, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits, true )
{
SetTitle( wxString::Format( GetTitle(), aShape->ShowShape() ) );
SetTitle( wxString::Format( GetTitle(), aShape->EDA_SHAPE::GetFriendlyName() ) );
m_helpLabel1->SetFont( KIUI::GetInfoFont( this ).Italic() );
m_helpLabel2->SetFont( KIUI::GetInfoFont( this ).Italic() );
@ -165,7 +165,10 @@ bool DIALOG_SHAPE_PROPERTIES::TransferDataFromWindow()
m_shape->SetFillColor( m_fillColorSwatch->GetSwatchColor() );
if( !commit.Empty() )
commit.Push( wxString::Format( _( "Edit %s" ), m_shape->ShowShape() ), SKIP_CONNECTIVITY );
{
commit.Push( wxString::Format( _( "Edit %s" ), m_shape->EDA_SHAPE::GetFriendlyName() ),
SKIP_CONNECTIVITY );
}
return true;
}

View File

@ -807,14 +807,12 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
{
SCH_SCREEN* screen = sheet.LastScreen();
std::vector<SCH_SYMBOL*> otherUnits;
constexpr bool appendUndo = true;
CollectOtherUnits( ref, unit, libId, sheet, &otherUnits );
for( SCH_SYMBOL* otherUnit : otherUnits )
{
GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
appendUndo );
commit.Modify( otherUnit, screen );
otherUnit->SetValueFieldText( m_fields->at( VALUE_FIELD ).GetText() );
otherUnit->SetFootprintFieldText( m_fields->at( FOOTPRINT_FIELD ).GetText() );

View File

@ -487,7 +487,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
OnModify();
}
RecalculateConnections( GLOBAL_CLEANUP );
RecalculateConnections( nullptr, GLOBAL_CLEANUP );
ClearUndoRedoList();
}
@ -1258,7 +1258,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
GetScreen()->SetFileName( newfilename.GetFullPath() );
GetScreen()->SetContentModified();
RecalculateConnections( GLOBAL_CLEANUP );
RecalculateConnections( nullptr, GLOBAL_CLEANUP );
// Only perform the dangling end test on root sheet.
GetScreen()->TestDanglingEnds();

View File

@ -32,36 +32,12 @@
#include <wildcards_and_files_ext.h>
#include <sch_edit_frame.h>
#include <symbol_lib_table.h>
#include <symbol_library.h>
#include <sch_symbol.h>
#include <sch_sheet.h>
#include <schematic.h>
bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename )
{
wxFileName fn;
if( aUseCurrentSheetFilename )
fn = GetScreen()->GetFileName();
else
fn = Schematic().RootScreen()->GetFileName();
fn.SetName( fn.GetName() + wxS( "-cache" ) );
fn.SetExt( LegacySymbolLibFileExtension );
bool success = CreateArchiveLibrary( fn.GetFullPath() );
// Update the schematic symbol library links.
// because the lib cache has changed
SCH_SCREENS schematic( Schematic().Root() );
schematic.UpdateSymbolLinks();
return success;
}
bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
{
wxString tmp;

View File

@ -55,7 +55,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
// If we are using the new connectivity, make sure that we do a full-rebuild
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
RecalculateConnections( GLOBAL_CLEANUP );
RecalculateConnections( nullptr, GLOBAL_CLEANUP );
bool res = true;
bool executeCommandLine = false;

View File

@ -53,6 +53,7 @@
#include <sch_sheet.h>
#include <sch_marker.h>
#include <schematic.h>
#include <schematic_commit.h>
#include <settings/settings_manager.h>
#include <advanced_config.h>
#include <sim/simulator_frame.h>
@ -1083,7 +1084,7 @@ void SCH_EDIT_FRAME::OnModify()
GetScreen()->SetContentModified();
m_autoSaveRequired = true;
RecalculateConnections( NO_CLEANUP );
RecalculateConnections( nullptr, NO_CLEANUP );
GetCanvas()->Refresh();
UpdateHierarchyNavigator();
@ -1588,8 +1589,8 @@ void SCH_EDIT_FRAME::AutoRotateItem( SCH_SCREEN* aScreen, SCH_ITEM* aItem )
}
void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem,
bool aUndoAppend )
void SCH_EDIT_FRAME::AddItemToCommitAndScreen( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen,
SCH_ITEM* aItem )
{
wxCHECK_RET( aItem != nullptr, wxT( "Cannot add null item to list." ) );
@ -1622,8 +1623,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM*
if( aItem->Type() == SCH_SHEET_PIN_T )
{
// Sheet pins are owned by their parent sheet.
SaveCopyInUndoList( aScreen, undoItem, UNDO_REDO::CHANGED, aUndoAppend );
aCommit->Modify( undoItem, aScreen );
parentSheet->AddPin( (SCH_SHEET_PIN*) aItem );
}
else if( aItem->Type() == SCH_FIELD_T )
@ -1638,12 +1638,12 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM*
AddToScreen( aItem, aScreen );
SaveCopyForRepeatItem( aItem );
SaveCopyInUndoList( aScreen, undoItem, UNDO_REDO::NEWITEM, aUndoAppend );
aCommit->Modify( undoItem, aScreen );
}
// Update connectivity info for new item
if( !aItem->IsMoving() && aItem->IsConnectable() )
RecalculateConnections( LOCAL_CLEANUP );
RecalculateConnections( aCommit, LOCAL_CLEANUP );
}
aItem->ClearFlags( IS_NEW );
@ -1656,22 +1656,21 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM*
std::vector<VECTOR2I> pts = aItem->GetConnectionPoints();
bool connected = true;
for( auto i = pts.begin(); i != pts.end(); i++ )
{
for( auto j = i + 1; j != pts.end(); j++ )
TrimWire( *i, *j );
TrimWire( aCommit, *i, *j );
if( aScreen->IsExplicitJunctionNeeded( *i ) )
{
AddJunction( aScreen, *i, true, false );
AddJunction( aCommit, aScreen, *i );
connected = true;
}
}
if( connected )
{
AutoRotateItem( aScreen, aItem );
}
TestDanglingEnds();
@ -1737,11 +1736,16 @@ void SCH_EDIT_FRAME::initScreenZoom()
}
void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
void SCH_EDIT_FRAME::RecalculateConnections( SCHEMATIC_COMMIT* aCommit,
SCH_CLEANUP_FLAGS aCleanupFlags )
{
wxString highlightedConn = GetHighlightedConnection();
SCHEMATIC_SETTINGS& settings = Schematic().Settings();
SCH_SHEET_LIST list = Schematic().GetSheets();
SCHEMATIC_COMMIT localInstance( m_toolManager );
if( !aCommit )
aCommit = &localInstance;
#ifdef PROFILE
PROF_TIMER timer;
@ -1750,12 +1754,12 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
// Ensure schematic graph is accurate
if( aCleanupFlags == LOCAL_CLEANUP )
{
SchematicCleanUp( GetScreen() );
SchematicCleanUp( aCommit, GetScreen() );
}
else if( aCleanupFlags == GLOBAL_CLEANUP )
{
for( const SCH_SHEET_PATH& sheet : list )
SchematicCleanUp( sheet.LastScreen() );
SchematicCleanUp( aCommit, sheet.LastScreen() );
}
#ifdef PROFILE
@ -1909,6 +1913,9 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
m_highlightedConnChanged = false;
}
if( !localInstance.Empty() )
localInstance.Push( _( "Schematic Cleanup" ) );
}

View File

@ -55,10 +55,10 @@ class SCH_SYMBOL;
class SCH_FIELD;
class SCH_JUNCTION;
class SCHEMATIC;
class SCHEMATIC_COMMIT;
class DIALOG_BOOK_REPORTER;
class DIALOG_ERC;
class DIALOG_SCH_FIND;
class wxFindReplaceData;
class RESCUER;
class HIERARCHY_PANE;
@ -248,10 +248,9 @@ public:
void AutoRotateItem( SCH_SCREEN* aScreen, SCH_ITEM* aItem );
/**
* Add an item to the schematic and adds the changes to the undo/redo container.
* @param aUndoAppend True if the action should be appended to the current undo record.
* Add an item to the schematic and adds the changes to the commit.
*/
void AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, bool aUndoAppend );
void AddItemToCommitAndScreen( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen, SCH_ITEM* aItem );
/**
* Run the Find or Find & Replace dialog.
@ -279,39 +278,33 @@ public:
/**
* Break a single segment into two at the specified point.
*
* @note This always appends to the existing undo state.
*
* @param aCommit Transaction container used to record changes for undo/redo
* @param aSegment Line segment to break
* @param aPoint Point at which to break the segment
* @param aNewSegment Pointer to the newly created segment (if given and created)
* @param aScreen is the screen to examine, or nullptr to examine the current screen.
* @param aNewSegment Pointer to the newly created segment (if created)
* @param aScreen is the screen to examine
*/
void BreakSegment( SCH_LINE* aSegment, const VECTOR2I& aPoint,
SCH_LINE** aNewSegment = nullptr, SCH_SCREEN* aScreen = nullptr );
void BreakSegment( SCHEMATIC_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint,
SCH_LINE** aNewSegment, SCH_SCREEN* aScreen );
/**
* Check every wire and bus for a intersection at \a aPoint and break into two segments
* at \a aPoint if an intersection is found.
*
* @note This always appends to the existing undo state.
*
* @param aCommit Transaction container used to record changes for undo/redo
* @param aPoint Test this point for an intersection.
* @param aScreen is the screen to examine, or nullptr to examine the current screen.
* @param aScreen is the screen to examine.
* @return True if any wires or buses were broken.
*/
bool BreakSegments( const VECTOR2I& aPoint, SCH_SCREEN* aScreen = nullptr );
bool BreakSegments( SCHEMATIC_COMMIT* aCommit, const VECTOR2I& aPoint, SCH_SCREEN* aScreen );
/**
* Test all junctions and bus entries in the schematic for intersections with wires and
* buses and breaks any intersections into multiple segments.
*
* @note This always appends to the existing undo state.
*
* @param aScreen is the screen to examine, or nullptr to examine the current screen
* @param aCommit Transaction container used to record changes for undo/redo
* @param aScreen is the screen to examine.
* @return True if any wires or buses were broken.
*/
bool BreakSegmentsOnJunctions( SCH_SCREEN* aScreen = nullptr );
bool BreakSegmentsOnJunctions( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen );
/**
* Test all of the connectable objects in the schematic for unused connection points.
@ -396,7 +389,7 @@ public:
* Annotate the symbols in the schematic that are not currently annotated. Multi-unit symbols
* are annotated together. E.g. if two symbols were R8A and R8B, they may become R3A and
* R3B, but not R3A and R3C or R3C and R4D.
*
* @param aCommit Transaction container used to record changes for undo/redo
* @param aAnnotateScope See #ANNOTATE_SCOPE_T
* @param aSortOption Define the annotation order. See #ANNOTATE_ORDER_T.
* @param aAlgoOption Define the annotation style. See #ANNOTATE_ALGO_T.
@ -410,17 +403,14 @@ public:
* used to handle annotation in complex hierarchies.
* @param aReporter A sink for error messages. Use NULL_REPORTER if you don't need errors.
*
* @param appendUndo True if the annotation operation should be added to an existing undo,
* false if it should be separately undo-able.
*
* When the sheet number is used in annotation, each sheet annotation starts from sheet
* number * 100. In other words the first sheet uses 100 to 199, the second sheet uses
* 200 to 299, and so on.
*/
void AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope, ANNOTATE_ORDER_T aSortOption,
ANNOTATE_ALGO_T aAlgoOption, bool aRecursive, int aStartNumber,
bool aResetAnnotation, bool aRepairTimestamps, REPORTER& aReporter,
bool appendUndo = false );
void AnnotateSymbols( SCHEMATIC_COMMIT* aCommit, ANNOTATE_SCOPE_T aAnnotateScope,
ANNOTATE_ORDER_T aSortOption, ANNOTATE_ALGO_T aAlgoOption,
bool aRecursive, int aStartNumber, bool aResetAnnotation,
bool aRepairTimestamps, REPORTER& aReporter );
/**
* Check for annotation errors.
@ -532,31 +522,26 @@ public:
*/
bool AskToSaveChanges();
SCH_JUNCTION* AddJunction( SCH_SCREEN* aScreen, const VECTOR2I& aPos, bool aAppendToUndo,
bool aFinal = true );
SCH_JUNCTION* AddJunction( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen,
const VECTOR2I& aPos );
/**
* Perform routine schematic cleaning including breaking wire and buses and deleting
* identical objects superimposed on top of each other.
*
* @note This always appends to the existing undo state.
*
* @param aCommit Transaction container used to record changes for undo/redo
* @param aScreen is the screen to examine, or nullptr to examine the current screen
* @return True if any schematic clean up was performed.
*/
bool SchematicCleanUp( SCH_SCREEN* aScreen = nullptr );
void SchematicCleanUp( SCHEMATIC_COMMIT* aCommit, SCH_SCREEN* aScreen = nullptr );
/**
* If any single wire passes through _both points_, remove the portion between the two points,
* potentially splitting the wire into two.
*
* @note This always appends to the existing undo state.
*
* @param aCommit Transaction container used to record changes for undo/redo
* @param aStart The starting point for trimmming
* @param aEnd The ending point for trimming
* @return True if any wires were changed by this operation
*/
bool TrimWire( const VECTOR2I& aStart, const VECTOR2I& aEnd );
bool TrimWire( SCHEMATIC_COMMIT* aCommit, const VECTOR2I& aStart, const VECTOR2I& aEnd );
void OnOpenPcbnew( wxCommandEvent& event );
void OnOpenCvpcb( wxCommandEvent& event );
@ -568,7 +553,6 @@ public:
*
* @param aSheet is the #SCH_SHEET object to test.
* @param aHierarchy is the #SCH_SHEET_PATH where \a aSheet is going to reside.
*
* @return true if \a aSheet will cause a recursion error in \a aHierarchy.
*/
bool CheckSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy );
@ -670,9 +654,8 @@ public:
* Removes a given junction and heals any wire segments under the junction
*
* @param aItem The junction to delete
* @param aAppend True if we are updating an ongoing commit
*/
void DeleteJunction( SCH_ITEM* aItem, bool aAppend = false );
void DeleteJunction( SCHEMATIC_COMMIT* aCommit, SCH_ITEM* aItem );
void ConvertPart( SCH_SYMBOL* aSymbol );
@ -680,11 +663,6 @@ public:
/* Undo - redo */
/**
* Create a new, blank stack for future Undo commands to be pushed to
*/
void StartNewUndo();
/**
* Create a copy of the current schematic item, and put it in the undo list.
*
@ -758,17 +736,6 @@ public:
*/
void RollbackSchematicFromUndo();
/**
* Create a symbol library file with the name of the root document plus the '-cache' suffix,
*
* This file will contain all symbols used in the current schematic.
*
* @param aUseCurrentSheetFilename set to false to use the root sheet filename
* (default) or true to use the currently opened sheet.
* @return true if the file was written successfully.
*/
bool CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename = false );
/**
* Create a library \a aFileName that contains all symbols used in the current schematic.
*
@ -809,7 +776,7 @@ public:
/**
* Generate the connection data for the entire schematic hierarchy.
*/
void RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags );
void RecalculateConnections( SCHEMATIC_COMMIT* aCommit, SCH_CLEANUP_FLAGS aCleanupFlags );
/**
* Called after the preferences dialog is run.

View File

@ -26,13 +26,9 @@
#include <tools/ee_tool_base.h>
#include <lib_item.h>
#include <lib_pin.h>
#include <lib_shape.h>
#include <lib_symbol.h>
#include <lib_text.h>
#include <sch_screen.h>
#include <sch_sheet_path.h>
#include <schematic.h>
#include <view/view.h>
@ -75,19 +71,33 @@ COMMIT& SCHEMATIC_COMMIT::Stage( EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_
// If aItem belongs a symbol, the full symbol will be saved because undo/redo does
// not handle "sub items" modifications.
if( aItem->GetParent() && aItem->GetParent()->IsType( { SCH_SYMBOL_T, LIB_SYMBOL_T } ) )
if( aItem->GetParent() && aItem->GetParent()->IsType( { SCH_SYMBOL_T, LIB_SYMBOL_T,
SCH_SHEET_T } ) )
{
aItem->SetFlags( IS_MODIFIED_CHILD );
aItem = aItem->GetParent();
aChangeType = CHT_MODIFY;
}
// IS_SELECTED flag should not be set on undo items which were added for
// a drag operation.
if( aItem->IsSelected() && aItem->HasFlag( SELECTED_BY_DRAG ) )
{
aItem->ClearSelected();
COMMIT::Stage( aItem, aChangeType, aScreen );
aItem->SetSelected();
}
else
{
COMMIT::Stage( aItem, aChangeType, aScreen );
}
return COMMIT::Stage( aItem, aChangeType, aScreen );
return *this;
}
COMMIT& SCHEMATIC_COMMIT::Stage( std::vector<EDA_ITEM*> &container, CHANGE_TYPE aChangeType,
BASE_SCREEN *aScreen )
BASE_SCREEN *aScreen )
{
for( EDA_ITEM* item : container )
Stage( item, aChangeType, aScreen );
@ -97,7 +107,7 @@ COMMIT& SCHEMATIC_COMMIT::Stage( std::vector<EDA_ITEM*> &container, CHANGE_TYPE
COMMIT& SCHEMATIC_COMMIT::Stage( const PICKED_ITEMS_LIST &aItems, UNDO_REDO aModFlag,
BASE_SCREEN *aScreen )
BASE_SCREEN *aScreen )
{
return COMMIT::Stage( aItems, aModFlag, aScreen );
}
@ -274,17 +284,17 @@ void SCHEMATIC_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
{
case CHT_ADD:
{
if( !schItem->GetParent() )
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( screen, schItem, UNDO_REDO::NEWITEM ) );
if( !( changeFlags & CHT_DONE ) )
{
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( screen, schItem, UNDO_REDO::NEWITEM ) );
if( !( changeFlags & CHT_DONE ) )
if( !schItem->GetParent() )
frame->GetScreen()->Append( schItem );
}
if( view )
view->Add( schItem );
if( view )
view->Add( schItem );
}
bulkAddedItems.push_back( schItem );
@ -310,14 +320,16 @@ void SCHEMATIC_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
break;
}
if( view )
view->Remove( schItem );
if( !( changeFlags & CHT_DONE ) )
{
frame->GetScreen()->Remove( schItem );
if( view )
view->Remove( schItem );
}
bulkRemovedItems.push_back( schItem );
if( !( changeFlags & CHT_DONE ) )
frame->GetScreen()->Remove( schItem );
break;
}
@ -406,8 +418,10 @@ EDA_ITEM* SCHEMATIC_COMMIT::parentObject( EDA_ITEM* aItem ) const
EDA_ITEM* SCHEMATIC_COMMIT::makeImage( EDA_ITEM* aItem ) const
{
if( m_isLibEditor )
return new LIB_SYMBOL(
*static_cast<SYMBOL_EDIT_FRAME*>( m_toolMgr->GetToolHolder() )->GetCurSymbol() );
{
SYMBOL_EDIT_FRAME* frame = static_cast<SYMBOL_EDIT_FRAME*>( m_toolMgr->GetToolHolder() );
return new LIB_SYMBOL( *frame->GetCurSymbol() );
}
return aItem->Clone();
}
@ -431,8 +445,8 @@ void SCHEMATIC_COMMIT::revertLibEdit()
void SCHEMATIC_COMMIT::Revert()
{
PICKED_ITEMS_LIST undoList;
KIGFX::VIEW* view = m_toolMgr->GetView();
PICKED_ITEMS_LIST undoList;
KIGFX::VIEW* view = m_toolMgr->GetView();
if( m_changes.empty() )
return;
@ -443,10 +457,11 @@ void SCHEMATIC_COMMIT::Revert()
return;
}
SCHEMATIC& schematic = static_cast<SCH_EDIT_FRAME*>( m_toolMgr->GetToolHolder() )->Schematic();
SCH_EDIT_FRAME* frame = static_cast<SCH_EDIT_FRAME*>( m_toolMgr->GetToolHolder() );
SCHEMATIC& schematic = frame->Schematic();
std::vector<SCH_ITEM*> bulkAddedItems;
std::vector<SCH_ITEM*> bulkRemovedItems;
std::vector<SCH_ITEM*> bulkRemovedItems;
std::vector<SCH_ITEM*> itemsChanged;
for( auto it = m_changes.rbegin(); it != m_changes.rend(); ++it )
@ -470,6 +485,8 @@ void SCHEMATIC_COMMIT::Revert()
break;
case CHT_REMOVE:
item->SetConnectivityDirty();
if( !( changeFlags & CHT_DONE ) )
break;
@ -482,6 +499,7 @@ void SCHEMATIC_COMMIT::Revert()
{
view->Remove( item );
item->SwapData( copy );
item->SetConnectivityDirty();
// Special cases for items which have instance data
if( item->GetParent() && item->GetParent()->Type() == SCH_SYMBOL_T
@ -521,6 +539,8 @@ void SCHEMATIC_COMMIT::Revert()
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
selTool->RebuildSelection();
frame->RecalculateConnections( nullptr, NO_CLEANUP );
clear();
}

View File

@ -96,13 +96,6 @@
* swapped data is data modified by editing, so not all values are swapped
*/
void SCH_EDIT_FRAME::StartNewUndo()
{
PICKED_ITEMS_LIST* blank = new PICKED_ITEMS_LIST();
PushCommandToUndoList( blank );
}
void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem,
UNDO_REDO aCommandType, bool aAppend,
bool aDirtyConnectivity )
@ -221,7 +214,9 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
{
if( !sch_item->IsConnectivityDirty() && sch_item->Connection()
&& ( sch_item->Connection()->Name() == m_highlightedConn ) )
{
m_highlightedConnChanged = true;
}
sch_item->SetConnectivityDirty();
}

View File

@ -994,7 +994,7 @@ bool SIMULATOR_FRAME::LoadSimulator()
// If we are using the new connectivity, make sure that we do a full-rebuild
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
m_schematicFrame->RecalculateConnections( GLOBAL_CLEANUP );
m_schematicFrame->RecalculateConnections( nullptr, GLOBAL_CLEANUP );
if( !m_simulator->Attach( m_circuitModel, reporter ) )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -33,6 +33,7 @@
#include <sch_sheet_path.h>
#include <sch_label.h>
#include <schematic.h>
#include <schematic_commit.h>
#include <string_utils.h>
#include <kiface_base.h>
#include <wildcards_and_files_ext.h>
@ -53,8 +54,7 @@ BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool
m_processAttributes( aProcessAttributes ),
m_dryRun( aDryRun ),
m_frame( aFrame ),
m_changesCount( 0 ),
m_appendUndo( false )
m_changesCount( 0 )
{
}
@ -67,7 +67,6 @@ BACK_ANNOTATE::~BACK_ANNOTATE()
bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
{
m_changesCount = 0;
m_appendUndo = false;
if( !m_matchByReference && !m_processValues && !m_processFootprints && !m_processReferences
&& !m_processNetNames && !m_processAttributes )
@ -226,8 +225,8 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
else
{
// Add footprint to the map
auto data =
std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM, pinNetMap );
auto data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
pinNetMap );
m_pcbFootprints.insert( nearestItem, std::make_pair( path, data ) );
}
}
@ -336,7 +335,8 @@ void BACK_ANNOTATE::checkForUnusedSymbols()
void BACK_ANNOTATE::applyChangelist()
{
wxString msg;
SCHEMATIC_COMMIT commit( m_frame );
wxString msg;
// Apply changes from change list
for( CHANGELIST_ITEM& item : m_changelist )
@ -365,8 +365,7 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
commit.Modify( symbol, screen );
symbol->SetRef( &ref.GetSheetPath(), fpData.m_ref );
}
@ -383,8 +382,7 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
commit.Modify( symbol, screen );
symbol->SetFootprintFieldText( fpData.m_footprint );
}
@ -401,8 +399,7 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
commit.Modify( symbol, screen );
symbol->SetValueFieldText( fpData.m_value );
}
@ -417,8 +414,7 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
commit.Modify( symbol, screen );
symbol->SetDNP( fpData.m_DNP );
}
@ -434,8 +430,7 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
commit.Modify( symbol, screen );
symbol->SetIncludeInBom( !fpData.m_excludeFromBOM );
}
@ -464,19 +459,21 @@ void BACK_ANNOTATE::applyChangelist()
if( connection && connection->Name( true ) != shortNetName )
{
processNetNameChange( ref.GetRef(), pin, connection,
processNetNameChange( &commit, ref.GetRef(), pin, connection,
connection->Name( true ), shortNetName );
}
}
}
// JEY TODO: back-annotate netclass changes?
// TODO: back-annotate netclass changes?
}
if( !m_dryRun )
{
m_frame->RecalculateConnections( NO_CLEANUP );
m_frame->RecalculateConnections( &commit, NO_CLEANUP );
m_frame->UpdateNetHighlightStatus();
commit.Push( _( "Update Schematic from PCB" ) );
}
}
@ -560,8 +557,8 @@ void addConnections( SCH_ITEM* aItem, const SCH_SHEET_PATH& aSheetPath,
}
void BACK_ANNOTATE::processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
const SCH_CONNECTION* aConnection,
void BACK_ANNOTATE::processNetNameChange( SCHEMATIC_COMMIT* aCommit, const wxString& aRef,
SCH_PIN* aPin, const SCH_CONNECTION* aConnection,
const wxString& aOldName, const wxString& aNewName )
{
wxString msg;
@ -603,10 +600,7 @@ void BACK_ANNOTATE::processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
if( !m_dryRun )
{
SCH_SCREEN* screen = aConnection->Sheet().LastScreen();
m_frame->SaveCopyInUndoList( screen, driver, UNDO_REDO::CHANGED, m_appendUndo );
m_appendUndo = true;
aCommit->Modify( driver, aConnection->Sheet().LastScreen() );
static_cast<SCH_LABEL_BASE*>( driver )->SetText( aNewName );
}
@ -644,8 +638,7 @@ void BACK_ANNOTATE::processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
label->SetFlags( IS_NEW );
SCH_SCREEN* screen = aConnection->Sheet().LastScreen();
m_frame->AddItemToScreenAndUndoList( screen, label, m_appendUndo );
m_appendUndo = true;
m_frame->AddItemToCommitAndScreen( aCommit, screen, label );
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,7 +37,7 @@
class REPORTER;
class SCH_SHEET_LIST;
class SCH_EDIT_FRAME;
class SCHEMATIC_COMMIT;
/**
* Back annotation algorithm class used to receive, check, and apply a \ref NETLIST from
@ -62,7 +62,7 @@ public:
{
PCB_FP_DATA( const wxString& aRef, const wxString& aFootprint, const wxString& aValue,
bool aDNP, bool aExcludeFromBOM,
const std::map<wxString, wxString> aPinMap ) :
const std::map<wxString, wxString>& aPinMap ) :
m_ref( aRef ),
m_footprint( aFootprint ),
m_value( aValue ),
@ -71,11 +71,11 @@ public:
m_pinMap( aPinMap )
{}
wxString m_ref;
wxString m_footprint;
wxString m_value;
bool m_DNP;
bool m_excludeFromBOM;
wxString m_ref;
wxString m_footprint;
wxString m_value;
bool m_DNP;
bool m_excludeFromBOM;
std::map<wxString, wxString> m_pinMap;
};
@ -131,7 +131,7 @@ private:
*/
void applyChangelist();
void processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
void processNetNameChange( SCHEMATIC_COMMIT* aCommit, const wxString& aRef, SCH_PIN* aPin,
const SCH_CONNECTION* aConnection, const wxString& aOldName,
const wxString& aNewName );
@ -152,7 +152,6 @@ private:
SCH_EDIT_FRAME* m_frame;
int m_changesCount; // Number of user-level changes
bool m_appendUndo;
};
#endif

View File

@ -34,9 +34,7 @@
#include <tools/ee_selection_tool.h>
#include <sch_edit_frame.h>
#include <sch_view.h>
#include <schematic_commit.h>
#include <symbol_edit_frame.h>
#include <undo_redo_container.h>
class EE_SELECTION;
@ -92,9 +90,6 @@ public:
m_isSymbolEditor = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame ) != nullptr;
}
if( aReason != RUN )
m_commit = std::make_unique<SCHEMATIC_COMMIT>( m_toolMgr );
m_view = static_cast<KIGFX::SCH_VIEW*>( getView() );
}
@ -201,8 +196,6 @@ protected:
KIGFX::SCH_VIEW* m_view;
EE_SELECTION_TOOL* m_selectionTool;
bool m_isSymbolEditor;
std::unique_ptr<SCHEMATIC_COMMIT> m_commit;
};

View File

@ -47,6 +47,7 @@
#include <sch_sheet_pin.h>
#include <sch_bitmap.h>
#include <schematic.h>
#include <schematic_commit.h>
#include <symbol_library_common.h>
#include <eeschema_settings.h>
#include <dialogs/dialog_label_properties.h>
@ -110,6 +111,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
std::vector<PICKED_SYMBOL>* historyList = nullptr;
bool ignorePrimePosition = false;
COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
SCHEMATIC_COMMIT commit( m_toolMgr );
EE_GRID_HELPER grid( m_toolMgr );
if( m_inPlaceSymbol )
@ -147,7 +149,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
m_frame->PushTool( aEvent );
auto addSymbol =
[&]( SCH_SYMBOL* aSymbol )
[this]( SCHEMATIC_COMMIT* aCommit, SCH_SYMBOL* aSymbol )
{
m_frame->SaveCopyForRepeatItem( aSymbol );
@ -156,9 +158,9 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
aSymbol->SetParent( m_frame->GetScreen() );
aSymbol->SetFlags( IS_NEW | IS_MOVING );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), aSymbol, false );
m_frame->AddItemToCommitAndScreen( aCommit, m_frame->GetScreen(), aSymbol );
// Set IS_MOVING again, as AddItemToScreenAndUndoList() will have cleared it.
// Set IS_MOVING again, as AddItemToCommitAndScreen() will have cleared it.
aSymbol->SetFlags( IS_MOVING );
m_toolMgr->RunAction( ACTIONS::refreshPreview );
};
@ -222,7 +224,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
// Prime the pump
if( symbol )
{
addSymbol( symbol );
addSymbol( &commit, symbol );
annotate();
getViewControls()->WarpMouseCursor( getViewControls()->GetMousePosition( false ) );
}
@ -323,7 +325,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
symbol = new SCH_SYMBOL( *libSymbol, &m_frame->GetCurrentSheet(), sel, cursorPos,
&m_frame->Schematic() );
addSymbol( symbol );
addSymbol( &commit, symbol );
annotate();
// Update the list of references for the next symbol placement.
@ -348,10 +350,10 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
m_frame->GetScreen()->Update( symbol );
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &m_selectionTool->GetSelection() );
lwbTool->AddJunctionsIfNeeded( &m_selectionTool->GetSelection() );
lwbTool->TrimOverLappingWires( &commit, &m_selectionTool->GetSelection() );
lwbTool->AddJunctionsIfNeeded( &commit, &m_selectionTool->GetSelection() );
m_frame->OnModify();
commit.Push( _( "Add Symbol" ) );
SCH_SYMBOL* nextSymbol = nullptr;
@ -381,8 +383,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
if( new_unit == 1 )
nextSymbol->ClearAnnotation( nullptr, false );
addSymbol( nextSymbol );
symbol = nextSymbol; // annotate() looks at symbol, update it
addSymbol( &commit, nextSymbol );
symbol = nextSymbol;
annotate();
// Update the list of references for the next symbol placement.
@ -641,7 +643,10 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
}
else
{
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), image, false );
SCHEMATIC_COMMIT commit( m_toolMgr );
m_frame->AddItemToCommitAndScreen( &commit, m_frame->GetScreen(), image );
commit.Push( _( "Add Image" ) );
image = nullptr;
m_toolMgr->RunAction( ACTIONS::activatePointEditor );
@ -700,6 +705,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
KIGFX::VIEW_CONTROLS* controls = getViewControls();
SCH_ITEM* previewItem;
bool loggedInfoBarError = false;
wxString description;
if( m_inSingleClickPlace )
return 0;
@ -725,16 +731,19 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
case SCH_NO_CONNECT_T:
previewItem = new SCH_NO_CONNECT( cursorPos );
previewItem->SetParent( m_frame->GetScreen() );
description = _( "Add No Connect Flag" );
break;
case SCH_JUNCTION_T:
previewItem = new SCH_JUNCTION( cursorPos );
previewItem->SetParent( m_frame->GetScreen() );
description = _( "Add Junction" );
break;
case SCH_BUS_WIRE_ENTRY_T:
previewItem = new SCH_BUS_WIRE_ENTRY( cursorPos );
previewItem->SetParent( m_frame->GetScreen() );
description = _( "Add Wire to Bus Entry" );
break;
default:
@ -824,14 +833,15 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
newItem->SetPosition( cursorPos );
newItem->SetFlags( IS_NEW );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), newItem, false );
SCHEMATIC_COMMIT commit( m_toolMgr );
m_frame->AddItemToCommitAndScreen( &commit, m_frame->GetScreen(), newItem );
if( type == SCH_JUNCTION_T )
m_frame->TestDanglingEnds();
else
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( &commit );
m_frame->OnModify();
commit.Push( description );
}
if( evt->IsDblClick( BUT_LEFT ) || type == SCH_SHEET_PIN_T ) // Finish tool.
@ -890,10 +900,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
DIALOG_WIRE_BUS_PROPERTIES dlg( m_frame, strokeItems );
if( dlg.ShowModal() == wxID_OK )
{
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
m_frame->OnModify();
}
}
break;
@ -905,10 +912,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
DIALOG_JUNCTION_PROPS dlg( m_frame, junctions );
if( dlg.ShowModal() == wxID_OK )
{
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
m_frame->OnModify();
}
}
break;
default:
@ -1115,6 +1119,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
bool ignorePrimePosition = false;
COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
SCH_SHEET* sheet = nullptr;
wxString description;
if( m_inTwoClickPlace )
return 0;
@ -1293,10 +1298,12 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( isText )
{
item = createNewText( cursorPos, LAYER_NOTES );
description = _( "Add Text" );
}
else if( isHierLabel )
{
item = createNewText( cursorPos, LAYER_HIERLABEL );
description = _( "Add Hierarchical Label" );
}
else if( isNetLabel || isGlobalLabel )
{
@ -1356,10 +1363,13 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
labelItem->SetText( netName );
item = labelItem;
}
description = _( "Add Label" );
}
else if( isClassLabel )
{
item = createNewText( cursorPos, LAYER_NETCLASS_REFS );
description = _( "Add Label" );
}
else if( isSheetPin )
{
@ -1387,6 +1397,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break;
}
}
description = _( "Add Sheet Pin" );
}
// If we started with a hotkey which has a position then warp back to that.
@ -1426,9 +1438,12 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
else // ... and second click places:
{
item->ClearFlags( IS_MOVING );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), item, false );
item = nullptr;
SCHEMATIC_COMMIT commit( m_toolMgr );
m_frame->AddItemToCommitAndScreen( &commit, m_frame->GetScreen(), item );
commit.Push( description );
item = nullptr;
m_view->ClearPreview();
// Exit the tool when this sheet runs out of pins for convenience
@ -1502,6 +1517,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
SCH_SHAPE* item = nullptr;
bool isTextBox = aEvent.IsAction( &EE_ACTIONS::drawTextBox );
SHAPE_T type = aEvent.Parameter<SHAPE_T>();
wxString description;
if( m_inDrawShape )
return 0;
@ -1611,6 +1627,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
textbox->SetParent( schematic );
item = textbox;
description = _( "Add Text Box" );
}
else
{
@ -1619,6 +1636,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
item->SetStroke( m_lastStroke );
item->SetFillColor( m_lastFillColor );
item->SetParent( schematic );
description = wxString::Format( _( "Add %s" ), item->EDA_SHAPE::GetFriendlyName() );
}
item->SetFlags( IS_NEW );
@ -1670,7 +1688,10 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
m_lastFillColor = item->GetFillColor();
}
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), item, false );
SCHEMATIC_COMMIT commit( m_toolMgr );
commit.Added( item, m_frame->GetScreen() );
commit.Push( wxString::Format( _( "Draw %s" ), item->GetClass() ) );
m_selectionTool->AddItemToSel( item );
item = nullptr;
@ -1859,7 +1880,10 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
{
sheet->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), sheet, false );
SCHEMATIC_COMMIT commit( m_toolMgr );
m_frame->AddItemToCommitAndScreen( &commit, m_frame->GetScreen(), sheet );
commit.Push( "Draw Sheet" );
m_frame->UpdateHierarchyNavigator();
m_selectionTool->AddItemToSel( sheet );
}

View File

@ -671,10 +671,15 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 0 )
return 0;
SCH_ITEM* head = nullptr;
int principalItemCount = 0; // User-selected items (as opposed to connected wires)
VECTOR2I rotPoint;
bool moving = false;
SCH_ITEM* head = nullptr;
int principalItemCount = 0; // User-selected items (as opposed to connected wires)
VECTOR2I rotPoint;
bool moving = false;
SCHEMATIC_COMMIT localInstance( m_toolMgr );
SCHEMATIC_COMMIT* commit = aEvent.Parameter<SCHEMATIC_COMMIT*>();
if( !commit )
commit = &localInstance;
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
{
@ -702,7 +707,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
rotPoint = m_frame->GetNearestHalfGridPosition( head->GetBoundingBox().GetCenter() );
if( !moving )
saveCopyInUndoList( head, UNDO_REDO::CHANGED );
commit->Modify( head, m_frame->GetScreen() );
switch( head->Type() )
{
@ -830,9 +835,9 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
rotPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
}
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
for( EDA_ITEM* edaItem : selection )
{
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
// We've already rotated the user selected item if there was only one. We're just
// here to rotate the ends of wires that were attached to it.
@ -840,7 +845,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
continue;
if( !moving )
saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
commit->Modify( item, m_frame->GetScreen() );
for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
{
@ -916,13 +921,14 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &selectionCopy );
lwbTool->AddJunctionsIfNeeded( &selectionCopy );
lwbTool->TrimOverLappingWires( commit, &selectionCopy );
lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( commit );
m_frame->TestDanglingEnds();
m_frame->OnModify();
if( !localInstance.Empty() )
localInstance.Push( _( "Rotate" ) );
}
return 0;
@ -936,15 +942,20 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 0 )
return 0;
bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
bool connections = false;
bool moving = item->IsMoving();
bool vertical = ( aEvent.Matches( EE_ACTIONS::mirrorV.MakeEvent() ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
bool connections = false;
bool moving = item->IsMoving();
SCHEMATIC_COMMIT localInstance( m_toolMgr );
SCHEMATIC_COMMIT* commit = aEvent.Parameter<SCHEMATIC_COMMIT*>();
if( !commit )
commit = &localInstance;
if( selection.GetSize() == 1 )
{
if( !moving )
saveCopyInUndoList( item, UNDO_REDO::CHANGED );
commit->Modify( item, m_frame->GetScreen() );
switch( item->Type() )
{
@ -1040,12 +1051,12 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
{
VECTOR2I mirrorPoint = m_frame->GetNearestHalfGridPosition( selection.GetCenter() );
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
for( EDA_ITEM* edaItem : selection )
{
item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
item = static_cast<SCH_ITEM*>( edaItem );
if( !moving )
saveCopyInUndoList( item, UNDO_REDO::CHANGED, ii > 0 );
commit->Modify( item, m_frame->GetScreen() );
if( item->Type() == SCH_SHEET_PIN_T )
{
@ -1110,14 +1121,15 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
if( connections )
{
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &selectionCopy );
lwbTool->AddJunctionsIfNeeded( &selectionCopy );
lwbTool->TrimOverLappingWires( commit, &selectionCopy );
lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( commit );
m_frame->TestDanglingEnds();
}
m_frame->OnModify();
if( !localInstance.Empty() )
localInstance.Push( _( "Mirror" ) );
}
return 0;
@ -1235,8 +1247,8 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
bool appendUndo = false;
EE_SELECTION newItems;
SCHEMATIC_COMMIT commit( m_toolMgr );
EE_SELECTION newItems;
for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
{
@ -1266,8 +1278,7 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem );
newItem->SetFlags( IS_NEW );
m_frame->AddToScreen( newItem, m_frame->GetScreen() );
m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, appendUndo );
appendUndo = true;
commit.Added( newItem, m_frame->GetScreen() );
if( newItem->Type() == SCH_SYMBOL_T )
{
@ -1279,13 +1290,19 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
{
static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
NULL_REPORTER reporter;
m_frame->AnnotateSymbols( ANNOTATE_SELECTION,
m_frame->AnnotateSymbols( &commit, ANNOTATE_SELECTION,
(ANNOTATE_ORDER_T) annotate.sort_order,
(ANNOTATE_ALGO_T) annotate.method, true /* recursive */,
annotateStartNum, false, false, reporter, appendUndo );
annotateStartNum, false, false, reporter );
}
m_toolMgr->RunAction( EE_ACTIONS::move, true );
m_toolMgr->RunAction( EE_ACTIONS::move, true, &commit );
while( m_toolMgr->GetTool<SCH_MOVE_TOOL>()->IsToolActive() )
{
wxMilliSleep( 50 );
wxYield();
}
}
newItems.Add( newItem );
@ -1296,15 +1313,17 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
if( !newItems.Empty() )
{
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &newItems );
lwbTool->AddJunctionsIfNeeded( &newItems );
lwbTool->TrimOverLappingWires( &commit, &newItems );
lwbTool->AddJunctionsIfNeeded( &commit, &newItems );
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( &commit );
m_frame->TestDanglingEnds();
}
m_frame->GetCanvas()->Refresh();
m_frame->OnModify();
if( !commit.Empty() )
commit.Push( _( "Repeat Item" ) );
if( !newItems.Empty() )
m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
@ -1343,7 +1362,7 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
{
SCH_SCREEN* screen = m_frame->GetScreen();
std::deque<EDA_ITEM*> items = m_selectionTool->RequestSelection( deletableItems ).GetItems();
bool appendToUndo = false;
SCHEMATIC_COMMIT commit( m_toolMgr );
std::vector<VECTOR2I> pts;
if( items.empty() )
@ -1381,31 +1400,23 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
if( !alg::contains( items, sheet ) )
{
pin->SetFlags( STRUCT_DELETED );
saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
appendToUndo = true;
updateItem( pin, false );
sheet->RemovePin( pin );
commit.Removed( pin, m_frame->GetScreen() );
}
}
else if( sch_item->Type() == SCH_FIELD_T )
{
saveCopyInUndoList( item, UNDO_REDO::CHANGED, appendToUndo );
commit.Modify( item, m_frame->GetScreen() );
static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
appendToUndo = true;
updateItem( sch_item, false );
}
else
{
sch_item->SetFlags( STRUCT_DELETED );
saveCopyInUndoList( item, UNDO_REDO::DELETED, appendToUndo );
appendToUndo = true;
updateItem( sch_item, false );
m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
commit.Removed( item, m_frame->GetScreen() );
if( sch_item->Type() == SCH_SHEET_T )
m_frame->UpdateHierarchyNavigator();
@ -1420,13 +1431,13 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
continue;
if( junction->HasFlag( STRUCT_DELETED ) || !screen->IsExplicitJunction( point ) )
m_frame->DeleteJunction( junction, appendToUndo );
m_frame->DeleteJunction( &commit, junction );
}
m_frame->TestDanglingEnds();
// m_frame->TestDanglingEnds();
m_frame->GetCanvas()->Refresh();
m_frame->OnModify();
commit.Push( _( "Delete" ) );
return 0;
}
@ -2329,15 +2340,19 @@ int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent )
if( selected )
m_toolMgr->RunAction( EE_ACTIONS::removeItemFromSel, true, item );
SCHEMATIC_COMMIT commit( m_toolMgr );
if( !item->IsNew() )
{
saveCopyInUndoList( item, UNDO_REDO::DELETED, i != 0 );
saveCopyInUndoList( newtext, UNDO_REDO::NEWITEM, true );
m_frame->RemoveFromScreen( item, m_frame->GetScreen() );
commit.Removed( item, m_frame->GetScreen() );
m_frame->AddToScreen( newtext, m_frame->GetScreen() );
commit.Added( newtext, m_frame->GetScreen() );
}
commit.Push( _( "Change Item Type" ) );
if( selected )
m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newtext );
@ -2372,6 +2387,8 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_LINE_T } );
SCH_SCREEN* screen = m_frame->GetScreen();
SCHEMATIC_COMMIT commit( m_toolMgr );
std::vector<SCH_LINE*> lines;
for( EDA_ITEM* item : selection )
@ -2384,7 +2401,6 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
}
m_selectionTool->ClearSelection();
m_frame->StartNewUndo();
for( SCH_LINE* line : lines )
{
@ -2392,9 +2408,9 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
// We let the user select the break point if they're on a single line
if( lines.size() == 1 && line->HitTest( cursorPos ) )
m_frame->BreakSegment( line, cursorPos, &newLine );
m_frame->BreakSegment( &commit, line, cursorPos, &newLine, screen );
else
m_frame->BreakSegment( line, line->GetMidPoint(), &newLine );
m_frame->BreakSegment( &commit, line, line->GetMidPoint(), &newLine, screen );
// Make sure both endpoints are deselected
newLine->ClearFlags();
@ -2417,11 +2433,18 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
if( !lines.empty() )
{
m_frame->TestDanglingEnds();
m_frame->OnModify();
m_frame->GetCanvas()->Refresh();
m_toolMgr->RunAction( EE_ACTIONS::drag, false, true );
m_toolMgr->RunAction( EE_ACTIONS::drag, true, &commit );
while( m_toolMgr->GetTool<SCH_MOVE_TOOL>()->IsToolActive() )
{
wxMilliSleep( 50 );
wxYield();
}
if( !commit.Empty() )
commit.Push( isSlice ? _( "Slice Wire" ) : _( "Break Wire" ) );
}
return 0;

View File

@ -31,12 +31,12 @@
#include <dialogs/dialog_plot_schematic.h>
#include <dialogs/dialog_symbol_remap.h>
#include <dialogs/dialog_assign_netclass.h>
#include <dialogs/dialog_update_from_pcb.h>
#include <project_rescue.h>
#include <erc.h>
#include <invoke_sch_dialog.h>
#include <string_utils.h>
#include <kiway.h>
#include <kiway_player.h>
#include <netlist_exporters/netlist_exporter_spice.h>
#include <paths.h>
#include <project/project_file.h>
@ -52,11 +52,11 @@
#include <sch_sheet_pin.h>
#include <sch_view.h>
#include <schematic.h>
#include <advanced_config.h>
#include <schematic_commit.h>
#include <sim/simulator_frame.h>
#include <sim/spice_generator.h>
#include <sim/sim_lib_mgr.h>
#include "symbol_library_manager.h"
#include <symbol_library_manager.h>
#include <symbol_viewer_frame.h>
#include <tool/picker_tool.h>
#include <tool/tool_manager.h>
@ -64,8 +64,8 @@
#include <tools/ee_selection.h>
#include <tools/ee_selection_tool.h>
#include <tools/sch_editor_control.h>
#include <tools/sch_move_tool.h>
#include <drawing_sheet/ds_proxy_undo_item.h>
#include <dialog_update_from_pcb.h>
#include <eda_list_dialog.h>
#include <wildcards_and_files_ext.h>
#include <wx_filename.h>
@ -247,7 +247,7 @@ bool SCH_EDITOR_CONTROL::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand
SCH_SCREENS schematic( m_frame->Schematic().Root() );
schematic.UpdateSymbolLinks();
m_frame->RecalculateConnections( GLOBAL_CLEANUP );
m_frame->RecalculateConnections( nullptr, GLOBAL_CLEANUP );
}
m_frame->ClearUndoRedoList();
@ -780,9 +780,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
if( item )
{
if( item->IsConnectivityDirty() )
{
editFrame->RecalculateConnections( NO_CLEANUP );
}
editFrame->RecalculateConnections( nullptr, NO_CLEANUP );
if( item->Type() == SCH_FIELD_T )
symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
@ -1529,18 +1527,19 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything
// else. Pull them back out to start with.
EDA_ITEMS loadedItems;
bool sheetsPasted = false;
SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets();
SCH_SHEET_PATH& pasteRoot = m_frame->GetCurrentSheet();
wxFileName destFn = pasteRoot.Last()->GetFileName();
SCHEMATIC_COMMIT commit( m_toolMgr );
EDA_ITEMS loadedItems;
bool sheetsPasted = false;
SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets();
SCH_SHEET_PATH& pasteRoot = m_frame->GetCurrentSheet();
wxFileName destFn = pasteRoot.Last()->GetFileName();
if( destFn.IsRelative() )
destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
// List of paths in the hierarchy that refer to the destination sheet of the paste
SCH_SHEET_LIST pasteInstances = hierarchy.FindAllSheetsForScreen( pasteRoot.LastScreen() );
pasteInstances.SortByPageNumbers();
SCH_SHEET_LIST sheetPathsForScreen = hierarchy.FindAllSheetsForScreen( pasteRoot.LastScreen() );
sheetPathsForScreen.SortByPageNumbers();
// Build a list of screens from the current design (to avoid loading sheets that already exist)
std::map<wxString, SCH_SCREEN*> loadedScreens;
@ -1594,9 +1593,8 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// Remove the references from our temporary screen to prevent freeing on the DTOR
tempScreen->Clear( false );
for( unsigned i = 0; i < loadedItems.size(); ++i )
for( EDA_ITEM* item : loadedItems )
{
EDA_ITEM* item = loadedItems[i];
KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
if( item->Type() == SCH_SYMBOL_T )
@ -1629,8 +1627,8 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
symbol->SetLibSymbol( libSymbol );
}
for( SCH_SHEET_PATH& instance : pasteInstances )
updatePastedSymbol( symbol, tempScreen, instance, clipPath, forceKeepAnnotations );
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
updatePastedSymbol( symbol, tempScreen, sheetPath, clipPath, forceKeepAnnotations );
// Assign a new KIID
const_cast<KIID&>( item->m_Uuid ) = KIID();
@ -1639,14 +1637,14 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
for( SCH_PIN* pin : symbol->GetPins() )
const_cast<KIID&>( pin->m_Uuid ) = KIID();
for( SCH_SHEET_PATH& instance : pasteInstances )
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
// Ignore symbols from a non-existant library.
if( libSymbol )
{
SCH_REFERENCE schReference( symbol, libSymbol, instance );
schReference.SetSheetNumber( instance.GetVirtualPageNumber() );
pastedSymbols[instance].AddItem( schReference );
SCH_REFERENCE schReference( symbol, libSymbol, sheetPath );
schReference.SetSheetNumber( sheetPath.GetVirtualPageNumber() );
pastedSymbols[sheetPath].AddItem( schReference );
}
}
}
@ -1724,14 +1722,14 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// Once we have our new KIID we can update all pasted instances. This will either
// reset the annotations or copy "kept" annotations from the supplementary clipboard.
for( SCH_SHEET_PATH& instance : pasteInstances )
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
SCH_SHEET_PATH sheetPath = updatePastedSheet( instance, clipPath, sheet,
( forceKeepAnnotations && annotate.automatic ),
&pastedSheets[instance],
&pastedSymbols[instance] );
SCH_SHEET_PATH subPath = updatePastedSheet( sheetPath, clipPath, sheet,
( forceKeepAnnotations && annotate.automatic ),
&pastedSheets[sheetPath],
&pastedSymbols[sheetPath] );
sheetPath.GetSymbols( pastedSymbols[instance] );
subPath.GetSymbols( pastedSymbols[sheetPath] );
}
}
else
@ -1754,7 +1752,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
item->SetFlags( STARTPOINT | ENDPOINT );
item->SetFlags( IS_NEW | IS_PASTED | IS_MOVING );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, i > 0 );
m_frame->AddItemToCommitAndScreen( &commit, m_frame->GetScreen(), (SCH_ITEM*) item );
// Reset flags for subsequent move operation
item->SetFlags( IS_NEW | IS_PASTED | IS_MOVING );
@ -1764,16 +1762,16 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
getView()->Hide( item, true );
}
pasteInstances.SortByPageNumbers();
sheetPathsForScreen.SortByPageNumbers();
if( sheetsPasted )
{
// Update page numbers: Find next free numeric page number
for( SCH_SHEET_PATH& instance : pasteInstances )
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
pastedSheets[instance].SortByPageNumbers();
pastedSheets[sheetPath].SortByPageNumbers();
for( SCH_SHEET_PATH& pastedSheet : pastedSheets[instance] )
for( SCH_SHEET_PATH& pastedSheet : pastedSheets[sheetPath] )
{
int page = 1;
wxString pageNum = wxString::Format( "%d", page );
@ -1797,7 +1795,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> annotatedSymbols;
// Update the list of symbol instances that satisfy the annotation criteria.
for( const SCH_SHEET_PATH& sheetPath : pasteInstances )
for( const SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
for( size_t i = 0; i < pastedSymbols[sheetPath].GetCount(); i++ )
{
@ -1812,24 +1810,27 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
if( !annotatedSymbols.empty() )
{
for( SCH_SHEET_PATH& instance : pasteInstances )
for( SCH_SHEET_PATH& path : sheetPathsForScreen )
{
annotatedSymbols[instance].SortByReferenceOnly();
annotatedSymbols[path].SortByReferenceOnly();
if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
annotatedSymbols[instance].ReannotateDuplicates( existingRefs );
{
annotatedSymbols[path].ReannotateDuplicates( existingRefs );
}
else
annotatedSymbols[instance].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
(ANNOTATE_ALGO_T) annotate.method,
annotateStartNum, existingRefs,
false,
&hierarchy );
{
annotatedSymbols[path].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
(ANNOTATE_ALGO_T) annotate.method,
annotateStartNum, existingRefs, false,
&hierarchy );
}
annotatedSymbols[instance].UpdateAnnotation();
annotatedSymbols[path].UpdateAnnotation();
// Update existing refs for next iteration
for( size_t i = 0; i < annotatedSymbols[instance].GetCount(); i++ )
existingRefs.AddItem( annotatedSymbols[instance][i] );
for( size_t i = 0; i < annotatedSymbols[path].GetCount(); i++ )
existingRefs.AddItem( annotatedSymbols[path][i] );
}
}
@ -1935,7 +1936,16 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
selection.SetReferencePoint( item->GetPosition() );
}
m_toolMgr->RunAction( EE_ACTIONS::move, false );
m_toolMgr->RunAction( EE_ACTIONS::move, true, &commit );
while( m_toolMgr->GetTool<SCH_MOVE_TOOL>()->IsToolActive() )
{
wxMilliSleep( 50 );
wxYield();
}
if( !commit.Empty() )
commit.Push( _( "Paste" ) );
}
return 0;
@ -2071,7 +2081,7 @@ int SCH_EDITOR_CONTROL::GenerateBOM( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::DrawSheetOnClipboard( const TOOL_EVENT& aEvent )
{
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->RecalculateConnections( nullptr, LOCAL_CLEANUP );
m_frame->DrawCurrentSheetToClipboard();
return 0;
}

View File

@ -35,9 +35,6 @@
#include <utility>
#include <vector>
#include <eda_item.h>
#include <bitmaps.h>
#include <core/typeinfo.h>
#include <layer_ids.h>
#include <math/vector2d.h>
#include <advanced_config.h>
@ -47,18 +44,16 @@
#include <tool/selection_conditions.h>
#include <tool/tool_event.h>
#include <trigo.h>
#include <undo_redo_container.h>
#include <connection_graph.h>
#include <eeschema_id.h>
#include <sch_bus_entry.h>
#include <sch_connection.h>
#include <sch_edit_frame.h>
#include <sch_item.h>
#include <sch_line.h>
#include <sch_screen.h>
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <schematic_commit.h>
#include <ee_actions.h>
#include <ee_grid_helper.h>
#include <ee_selection.h>
@ -819,8 +814,10 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const TOOL_EVENT& aTool, int aType,
if( evt->IsDblClick( BUT_LEFT ) && segment )
{
if( twoSegments && m_wires.size() >= 2 )
{
computeBreakPoint( { m_wires[m_wires.size() - 2], segment }, cursorPos,
currentMode, posture );
}
finishSegments();
segment = nullptr;
@ -1123,8 +1120,8 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
// freed selected items.
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
SCH_SCREEN* screen = m_frame->GetScreen();
PICKED_ITEMS_LIST itemList;
SCH_SCREEN* screen = m_frame->GetScreen();
SCHEMATIC_COMMIT commit( m_toolMgr );
// Remove segments backtracking over others
simplifyWireList();
@ -1149,17 +1146,17 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
new_ends.push_back( pt );
}
itemList.PushItem( ITEM_PICKER( screen, wire, UNDO_REDO::NEWITEM ) );
commit.Added( wire, screen );
}
if( m_busUnfold.in_progress && m_busUnfold.label_placed )
{
wxASSERT( m_busUnfold.entry && m_busUnfold.label );
itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.entry, UNDO_REDO::NEWITEM ) );
commit.Added( m_busUnfold.entry, screen );
m_frame->SaveCopyForRepeatItem( m_busUnfold.entry );
itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.label, UNDO_REDO::NEWITEM ) );
commit.Added( m_busUnfold.label, screen );
m_frame->AddCopyForRepeatItem( m_busUnfold.label );
m_busUnfold.label->ClearEditFlags();
}
@ -1189,10 +1186,8 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
getViewControls()->CaptureCursor( false );
getViewControls()->SetAutoPan( false );
m_frame->SaveCopyInUndoList( itemList, UNDO_REDO::NEWITEM, false );
// Correct and remove segments that need to be merged.
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( &commit );
std::vector<SCH_ITEM*> symbols;
@ -1209,14 +1204,14 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
for( auto pt = pts.begin(); pt != pts.end(); pt++ )
{
for( auto secondPt = pt + 1; secondPt != pts.end(); secondPt++ )
m_frame->TrimWire( *pt, *secondPt );
m_frame->TrimWire( &commit, *pt, *secondPt );
}
}
for( const VECTOR2I& pt : new_ends )
{
if( m_frame->GetScreen()->IsExplicitJunctionNeeded( pt ) )
m_frame->AddJunction( m_frame->GetScreen(), pt, true, false );
m_frame->AddJunction( &commit, m_frame->GetScreen(), pt );
}
if( m_busUnfold.in_progress )
@ -1226,13 +1221,14 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
item->ClearEditFlags();
m_frame->TestDanglingEnds();
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
commit.Push( _( "Draw Wires" ) );
m_frame->OnModify();
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
}
int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( EE_SELECTION* aSelection )
int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( SCHEMATIC_COMMIT* aCommit,
EE_SELECTION* aSelection )
{
SCHEMATIC* sch = getModel<SCHEMATIC>();
SCH_SCREEN* screen = sch->CurrentSheet().LastScreen();
@ -1258,7 +1254,7 @@ int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( EE_SELECTION* aSelection )
{
std::vector<VECTOR2I> conn_pts;
for( VECTOR2I pt : pts )
for( const VECTOR2I& pt : pts )
{
if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), pt ) )
conn_pts.push_back( pt );
@ -1268,7 +1264,7 @@ int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( EE_SELECTION* aSelection )
}
if( conn_pts.size() == 2 )
m_frame->TrimWire( conn_pts[0], conn_pts[1] );
m_frame->TrimWire( aCommit, conn_pts[0], conn_pts[1] );
}
}
@ -1276,12 +1272,13 @@ int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( EE_SELECTION* aSelection )
}
int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( EE_SELECTION* aSelection )
int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( SCHEMATIC_COMMIT* aCommit,
EE_SELECTION* aSelection )
{
SCH_SCREEN* screen = m_frame->GetScreen();
for( const VECTOR2I& point : screen->GetNeededJunctions( aSelection->Items() ) )
m_frame->AddJunction( m_frame->GetScreen(), point, true, false );
m_frame->AddJunction( aCommit, m_frame->GetScreen(), point );
return 0;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -92,17 +92,20 @@ public:
/**
* Handle the addition of junctions to a selection of objects
*/
int AddJunctionsIfNeeded( EE_SELECTION* aSelection );
int AddJunctionsIfNeeded( SCHEMATIC_COMMIT* aCommit, EE_SELECTION* aSelection );
/**
* Logic to remove wires when overlapping correct items
*/
int TrimOverLappingWires( EE_SELECTION* aSelection );
int TrimOverLappingWires( SCHEMATIC_COMMIT* aCommit, EE_SELECTION* aSelection );
private:
int doDrawSegments( const TOOL_EVENT& aTool, int aType, bool aQuitOnDraw );
int doDrawSegments( const TOOL_EVENT& aTool, int aType, bool aQuitOnDraw );
SCH_LINE* startSegments( int aType, const VECTOR2D& aPos, SCH_LINE* aSegment = nullptr );
SCH_LINE* doUnfoldBus( const wxString& aNet, const VECTOR2I& aPos = VECTOR2I( 0, 0 ) );
void finishSegments();
/**

View File

@ -30,6 +30,7 @@
#include <tools/ee_selection_tool.h>
#include <tools/sch_line_wire_bus_tool.h>
#include <ee_actions.h>
#include <schematic_commit.h>
#include <eda_item.h>
#include <sch_item.h>
#include <sch_symbol.h>
@ -359,6 +360,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
EE_GRID_HELPER grid( m_toolMgr );
bool wasDragging = m_moveInProgress && m_isDrag;
bool isSlice = false;
SCHEMATIC_COMMIT localInstance( m_toolMgr );
SCHEMATIC_COMMIT* commit = aEvent.Parameter<SCHEMATIC_COMMIT*>();
if( !commit )
commit = &localInstance;
m_anchorPos.reset();
@ -369,7 +375,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
else if( aEvent.IsAction( &EE_ACTIONS::drag ) )
{
m_isDrag = true;
isSlice = aEvent.Parameter<bool>();
isSlice = commit != &localInstance;
}
else if( aEvent.IsAction( &EE_ACTIONS::moveActivate ) )
{
@ -392,7 +398,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
// state.
try
{
m_frame->RollbackSchematicFromUndo();
commit->Revert();
}
catch( const IO_ERROR& exc )
{
@ -475,7 +481,6 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( !m_moveInProgress ) // Prepare to start moving/dragging
{
SCH_ITEM* sch_item = (SCH_ITEM*) selection.Front();
bool appendUndo = ( sch_item && sch_item->IsNew() ) || isSlice;
bool placingNewItems = sch_item && sch_item->IsNew();
//------------------------------------------------------------------------
@ -528,7 +533,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
}
for( const VECTOR2I& point : connections )
getConnectedDragItems( item, point, connectedDragItems, appendUndo );
getConnectedDragItems( commit, item, point, connectedDragItems );
}
// Go back and get all label connections now that we can test for drag-selected
@ -536,7 +541,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
for( SCH_ITEM* item : stageTwo )
{
for( const VECTOR2I& point : item->GetConnectionPoints() )
getConnectedDragItems( item, point, connectedDragItems, appendUndo );
getConnectedDragItems( commit, item, point, connectedDragItems );
}
for( EDA_ITEM* item : connectedDragItems )
@ -595,17 +600,15 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( item->IsNew() )
{
// Item was added in a previous command (and saved to undo by
// that command)
// Item was added to commit in a previous command
}
else if( item->GetParent() && item->GetParent()->IsSelected() )
{
// Item will be (or has been) saved to undo by parent
// Item will be (or has been) added to commit by parent
}
else
{
saveCopyInUndoList( (SCH_ITEM*) item, UNDO_REDO::CHANGED, appendUndo, false );
appendUndo = true;
commit->Modify( (SCH_ITEM*) item, m_frame->GetScreen() );
}
SCH_ITEM* schItem = (SCH_ITEM*) item;
@ -840,11 +843,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
}
else if( evt->IsAction( &EE_ACTIONS::rotateCW ) )
{
m_toolMgr->RunAction( EE_ACTIONS::rotateCW, true );
m_toolMgr->RunAction( EE_ACTIONS::rotateCW, true, &commit );
}
else if( evt->IsAction( &EE_ACTIONS::rotateCCW ) )
{
m_toolMgr->RunAction( EE_ACTIONS::rotateCCW, true );
m_toolMgr->RunAction( EE_ACTIONS::rotateCCW, true, &commit );
}
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
{
@ -903,7 +906,19 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
selectionCopy.Add( line );
// Save whatever new bend lines and changed lines survived the drag
commitDragLines();
for( SCH_LINE* newLine : m_newDragLines )
{
newLine->ClearEditFlags();
commit->Added( newLine, m_frame->GetScreen() );
}
// These lines have been changed, but aren't selected. We need
// to manually clear these edit flags or they'll stick around.
for( SCH_LINE* oldLine : m_changedDragLines )
oldLine->ClearEditFlags();
m_newDragLines.clear();
m_changedDragLines.clear();
controls->ForceCursorPosition( false );
controls->ShowCursor( false );
@ -917,7 +932,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( restore_state )
{
m_selectionTool->RemoveItemsFromSel( &m_dragAdditions, QUIET_MODE );
m_frame->RollbackSchematicFromUndo();
commit->Revert();
}
else
{
@ -937,24 +952,26 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
for( const DANGLING_END_ITEM& it : internalPoints )
{
if( m_frame->GetScreen()->IsExplicitJunctionNeeded( it.GetPosition()) )
m_frame->AddJunction( m_frame->GetScreen(), it.GetPosition(), true, false );
m_frame->AddJunction( commit, m_frame->GetScreen(), it.GetPosition() );
}
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &selectionCopy );
lwbTool->AddJunctionsIfNeeded( &selectionCopy );
lwbTool->TrimOverLappingWires( commit, &selectionCopy );
lwbTool->AddJunctionsIfNeeded( commit, &selectionCopy );
// This needs to run prior to `RecalculateConnections` because we need to identify
// the lines that are newly dangling
if( m_isDrag && !isSlice )
trimDanglingLines();
trimDanglingLines( commit );
// Auto-rotate any moved labels
for( EDA_ITEM* item : selection )
m_frame->AutoRotateItem( m_frame->GetScreen(), static_cast<SCH_ITEM*>( item ) );
m_frame->SchematicCleanUp();
m_frame->OnModify();
m_frame->SchematicCleanUp( commit );
if( commit == &localInstance )
commit->Push( m_isDrag ? _( "Drag" ) : _( "Move" ) );
}
for( EDA_ITEM* item : m_frame->GetScreen()->Items() )
@ -979,10 +996,10 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
}
void SCH_MOVE_TOOL::trimDanglingLines()
void SCH_MOVE_TOOL::trimDanglingLines( SCHEMATIC_COMMIT* aCommit )
{
// Need a local cleanup first to ensure we remove unneeded junctions
m_frame->SchematicCleanUp( m_frame->GetScreen() );
m_frame->SchematicCleanUp( aCommit, m_frame->GetScreen() );
std::set<SCH_ITEM*> danglers;
@ -1006,10 +1023,9 @@ void SCH_MOVE_TOOL::trimDanglingLines()
for( SCH_ITEM* line : danglers )
{
line->SetFlags( STRUCT_DELETED );
saveCopyInUndoList( line, UNDO_REDO::DELETED, true );
aCommit->Removed( line, m_frame->GetScreen() );
updateItem( line, false );
m_frame->RemoveFromScreen( line, m_frame->GetScreen() );
}
}
@ -1144,8 +1160,8 @@ void SCH_MOVE_TOOL::getConnectedItems( SCH_ITEM* aOriginalItem, const VECTOR2I&
}
void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR2I& aPoint,
EDA_ITEMS& aList, bool& aAppendUndo )
void SCH_MOVE_TOOL::getConnectedDragItems( SCHEMATIC_COMMIT* aCommit, SCH_ITEM* aSelectedItem,
const VECTOR2I& aPoint, EDA_ITEMS& aList )
{
EE_RTREE& items = m_frame->GetScreen()->Items();
EE_RTREE::EE_TYPE itemsOverlappingRTree = items.Overlapping( aSelectedItem->GetBoundingBox() );
@ -1153,7 +1169,8 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
bool ptHasUnselectedJunction = false;
auto makeNewWire =
[&]( SCH_ITEM* fixed, SCH_ITEM* selected, const VECTOR2I& start, const VECTOR2I& end )
[this]( SCHEMATIC_COMMIT* commit, SCH_ITEM* fixed, SCH_ITEM* selected,
const VECTOR2I& start, const VECTOR2I& end )
{
SCH_LINE* newWire;
@ -1175,12 +1192,13 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
newWire->SetEndPoint( end );
m_frame->AddToScreen( newWire, m_frame->GetScreen() );
commit->Added( newWire, m_frame->GetScreen() );
return newWire;
};
auto makeNewJunction =
[&]( SCH_LINE* line, const VECTOR2I& pt )
[this]( SCHEMATIC_COMMIT* commit, SCH_LINE* line, const VECTOR2I& pt )
{
SCH_JUNCTION* junction = new SCH_JUNCTION( pt );
junction->SetFlags( IS_NEW );
@ -1191,6 +1209,7 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
junction->SetLayer( LAYER_BUS_JUNCTION );
m_frame->AddToScreen( junction, m_frame->GetScreen() );
commit->Added( junction, m_frame->GetScreen() );
return junction;
};
@ -1282,34 +1301,22 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
if( line->HitTest( aPoint, 1 ) && !line->HasFlag( SELECTED )
&& !line->HasFlag( SELECTED_BY_DRAG ) )
{
newWire = makeNewWire( line, aSelectedItem, aPoint, aPoint );
newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
newWire->SetFlags( SELECTED_BY_DRAG | STARTPOINT );
newWire->StoreAngle( ( line->Angle() + ANGLE_90 ).Normalize() );
aList.push_back( newWire );
saveCopyInUndoList( newWire, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
if( aPoint != line->GetStartPoint() && aPoint != line->GetEndPoint() )
{
// Split line in half
if( !line->IsNew() )
{
saveCopyInUndoList( line, UNDO_REDO::CHANGED, aAppendUndo );
aAppendUndo = true;
}
aCommit->Modify( line, m_frame->GetScreen() );
VECTOR2I oldEnd = line->GetEndPoint();
line->SetEndPoint( aPoint );
SCH_LINE* secondHalf = makeNewWire( line, line, aPoint, oldEnd );
SCH_JUNCTION* junction = makeNewJunction( line, aPoint );
saveCopyInUndoList( secondHalf, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
saveCopyInUndoList( junction, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
makeNewWire( aCommit, line, line, aPoint, oldEnd );
makeNewJunction( aCommit, line, aPoint );
}
else
{
@ -1367,12 +1374,9 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
{
// Add a new wire between the sheetpin and the selected item so the
// selected item can be dragged.
newWire = makeNewWire( pin, aSelectedItem, aPoint, aPoint );
newWire = makeNewWire( aCommit, pin, aSelectedItem, aPoint, aPoint );
newWire->SetFlags( SELECTED_BY_DRAG | STARTPOINT );
aList.push_back( newWire );
saveCopyInUndoList( newWire, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
}
}
}
@ -1385,12 +1389,9 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
{
// Add a new wire between the symbol or junction and the selected item so
// the selected item can be dragged.
newWire = makeNewWire( test, aSelectedItem, aPoint, aPoint );
newWire = makeNewWire( aCommit, test, aSelectedItem, aPoint, aPoint );
newWire->SetFlags( SELECTED_BY_DRAG | STARTPOINT );
aList.push_back( newWire );
saveCopyInUndoList( newWire, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
}
break;
@ -1451,12 +1452,9 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
{
// Add a new wire between the label and the selected item so the selected item
// can be dragged.
newWire = makeNewWire( test, aSelectedItem, aPoint, aPoint );
newWire = makeNewWire( aCommit, test, aSelectedItem, aPoint, aPoint );
newWire->SetFlags( SELECTED_BY_DRAG | STARTPOINT );
aList.push_back( newWire );
saveCopyInUndoList( newWire, UNDO_REDO::NEWITEM, aAppendUndo );
aAppendUndo = true;
}
break;
@ -1496,7 +1494,7 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aSelectedItem, const VECTOR
else
otherEnd = ends[0];
getConnectedDragItems( test, otherEnd, aList, aAppendUndo );
getConnectedDragItems( aCommit, test, otherEnd, aList );
// No need to test the other end of the bus entry
break;
@ -1594,15 +1592,15 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
{
EE_GRID_HELPER grid( m_toolMgr);
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems );
bool appendUndo = false;
EE_GRID_HELPER grid( m_toolMgr);
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems );
SCHEMATIC_COMMIT commit( m_toolMgr );
auto doMoveItem =
[&]( EDA_ITEM* item, const VECTOR2I& delta )
{
saveCopyInUndoList( item, UNDO_REDO::CHANGED, appendUndo );
appendUndo = true;
commit.Modify( item, m_frame->GetScreen() );
// Ensure only one end is moved when calling moveItem
// i.e. we are in drag mode
bool tmp_isDrag = m_isDrag;
@ -1645,7 +1643,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
line->ClearFlags();
line->SetFlags( SELECTED );
line->SetFlags( flags[ii] );
getConnectedDragItems( line, pts[ii], drag_items, appendUndo );
getConnectedDragItems( &commit, line, pts[ii], drag_items );
std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
VECTOR2I gridpt = grid.AlignGrid( pts[ii] ) - pts[ii];
@ -1697,8 +1695,8 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
if( gridpt != VECTOR2I( 0, 0 ) )
{
EDA_ITEMS drag_items;
getConnectedDragItems( pin, pin->GetConnectionPoints()[0], drag_items,
appendUndo );
getConnectedDragItems( &commit, pin, pin->GetConnectionPoints()[0],
drag_items );
doMoveItem( pin, gridpt );
@ -1720,7 +1718,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
EDA_ITEMS drag_items{ item };
for( const VECTOR2I& point : connections )
getConnectedDragItems( schItem, point, drag_items, appendUndo );
getConnectedDragItems( &commit, schItem, point, drag_items );
std::map<VECTOR2I, int> shifts;
VECTOR2I most_common( 0, 0 );
@ -1753,39 +1751,19 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
}
SCH_LINE_WIRE_BUS_TOOL* lwbTool = m_toolMgr->GetTool<SCH_LINE_WIRE_BUS_TOOL>();
lwbTool->TrimOverLappingWires( &selection );
lwbTool->AddJunctionsIfNeeded( &selection );
lwbTool->TrimOverLappingWires( &commit, &selection );
lwbTool->AddJunctionsIfNeeded( &commit, &selection );
m_toolMgr->PostEvent( EVENTS::SelectedItemsMoved );
m_frame->SchematicCleanUp();
m_frame->SchematicCleanUp( &commit );
m_frame->TestDanglingEnds();
commit.Push( _( "Align" ) );
m_frame->OnModify();
return 0;
}
void SCH_MOVE_TOOL::commitDragLines()
{
for( SCH_LINE* newLine : m_newDragLines )
{
newLine->ClearEditFlags();
saveCopyInUndoList( newLine, UNDO_REDO::NEWITEM, true );
}
// These lines have been changed, but aren't selected. We need
// to manually clear these edit flags or they'll stick around.
for( SCH_LINE* oldLine : m_changedDragLines )
{
oldLine->ClearEditFlags();
}
m_newDragLines.clear();
m_changedDragLines.clear();
}
void SCH_MOVE_TOOL::clearNewDragLines()
{
// Remove new bend lines added during the drag

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -69,15 +69,12 @@ private:
///< Connected items with no wire are included (as there is no wire to adjust for the drag).
///< Connected wires are included with any un-connected ends flagged (STARTPOINT or ENDPOINT).
void getConnectedItems( SCH_ITEM* aOriginalItem, const VECTOR2I& aPoint, EDA_ITEMS& aList );
void getConnectedDragItems( SCH_ITEM* fixed, const VECTOR2I& selected, EDA_ITEMS& aList,
bool& aAppendUndo );
void getConnectedDragItems( SCHEMATIC_COMMIT* aCommit, SCH_ITEM* fixed,
const VECTOR2I& selected, EDA_ITEMS& aList );
void orthoLineDrag( SCH_LINE* line, const VECTOR2I& splitDelta, int& xBendCount,
int& yBendCount, const EE_GRID_HELPER& grid );
///< Saves the new drag lines to the undo list
void commitDragLines();
///< Clears the new drag lines and removes them from the screen
void clearNewDragLines();
@ -85,7 +82,7 @@ private:
void setTransitions() override;
///< Cleanup dangling lines left after a drag
void trimDanglingLines();
void trimDanglingLines( SCHEMATIC_COMMIT* aCommit );
private:
///< Re-entrancy guard

View File

@ -28,20 +28,20 @@
#include <tools/symbol_editor_drawing_tools.h>
#include <tools/symbol_editor_move_tool.h>
#include <ee_actions.h>
#include <bitmaps.h>
#include <string_utils.h>
#include <symbol_edit_frame.h>
#include <schematic_commit.h>
#include <dialogs/dialog_lib_shape_properties.h>
#include <dialogs/dialog_lib_text_properties.h>
#include <dialogs/dialog_lib_textbox_properties.h>
#include <dialogs/dialog_field_properties.h>
#include <dialogs/dialog_lib_symbol_properties.h>
#include <dialogs/dialog_lib_edit_pin_table.h>
#include <dialogs/dialog_update_symbol_fields.h>
#include <sch_plugins/kicad/sch_sexpr_plugin.h>
#include <lib_text.h>
#include <lib_textbox.h>
#include "symbol_editor_edit_tool.h"
#include "dialog_lib_textbox_properties.h"
#include "lib_textbox.h"
#include <wx/textdlg.h> // for wxTextEntryDialog
#include <math/util.h> // for KiROUND
@ -755,7 +755,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Copy( const TOOL_EVENT& aEvent )
int SYMBOL_EDITOR_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
{
LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
if( !symbol || symbol->IsAlias() )
return 0;
@ -780,7 +780,9 @@ int SYMBOL_EDITOR_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
if( !newPart )
return -1;
m_frame->SaveCopyInUndoList( symbol );
SCHEMATIC_COMMIT commit( m_toolMgr );
commit.Modify( symbol );
m_selectionTool->ClearSelection();
for( LIB_ITEM& item : symbol->GetDrawItems() )
@ -811,7 +813,8 @@ int SYMBOL_EDITOR_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
if( !selection.Empty() )
{
selection.SetReferencePoint( getViewControls()->GetCursorPosition( true ) );
m_toolMgr->RunAction( EE_ACTIONS::move, false );
m_toolMgr->RunAction( EE_ACTIONS::move, true, &commit );
commit.Push( _( "Paste" ) );
}
return 0;
@ -820,8 +823,9 @@ int SYMBOL_EDITOR_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
int SYMBOL_EDITOR_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
{
LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
EE_SELECTION& selection = m_selectionTool->RequestSelection( nonFields );
LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
EE_SELECTION& selection = m_selectionTool->RequestSelection( nonFields );
SCHEMATIC_COMMIT commit( m_toolMgr );
if( selection.GetSize() == 0 )
return 0;
@ -832,7 +836,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
return 0;
if( !selection.Front()->IsMoving() )
saveCopyInUndoList( m_frame->GetCurSymbol(), UNDO_REDO::LIBEDIT );
commit.Modify( symbol, m_frame->GetScreen() );
EDA_ITEMS newItems;
int symbolLastPinNumber = -1;
@ -866,7 +870,8 @@ int SYMBOL_EDITOR_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::addItemsToSel, true, &newItems );
selection.SetReferencePoint( mapCoords( getViewControls()->GetCursorPosition( true ) ) );
m_toolMgr->RunAction( EE_ACTIONS::move, false );
m_toolMgr->RunAction( EE_ACTIONS::move, true, &commit );
commit.Push( _( "Duplicate" ) );
return 0;
}

View File

@ -344,7 +344,7 @@ void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
wxString PCB_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
{
return wxString::Format( _( "%s on %s" ), ShowShape(), GetLayerName() );
return wxString::Format( _( "%s on %s" ), GetFriendlyName(), GetLayerName() );
}