diff --git a/eeschema/sch_commit.cpp b/eeschema/sch_commit.cpp index 1c61a668bb..17105ee45d 100644 --- a/eeschema/sch_commit.cpp +++ b/eeschema/sch_commit.cpp @@ -40,6 +40,7 @@ SCH_COMMIT::SCH_COMMIT( TOOL_MANAGER* aToolMgr ) : + COMMIT(), m_toolMgr( aToolMgr ), m_isLibEditor( false ) { @@ -128,19 +129,13 @@ COMMIT& SCH_COMMIT::Stage( const PICKED_ITEMS_LIST &aItems, UNDO_REDO aModFlag, void SCH_COMMIT::pushLibEdit( const wxString& aMessage, int aCommitFlags ) { - KIGFX::VIEW* view = m_toolMgr->GetView(); - SYMBOL_EDIT_FRAME* frame = static_cast( m_toolMgr->GetToolHolder() ); - - if( Empty() ) - return; - // Symbol editor just saves copies of the whole symbol, so grab the first and discard the rest LIB_SYMBOL* symbol = dynamic_cast( m_changes.front().m_item ); LIB_SYMBOL* copy = dynamic_cast( m_changes.front().m_copy ); if( symbol ) { - if( view ) + if( KIGFX::VIEW* view = m_toolMgr->GetView() ) { view->Update( symbol ); @@ -152,12 +147,15 @@ void SCH_COMMIT::pushLibEdit( const wxString& aMessage, int aCommitFlags ) RECURSE_MODE::NO_RECURSE ); } - if( !( aCommitFlags & SKIP_UNDO ) ) + if( SYMBOL_EDIT_FRAME* frame = static_cast( m_toolMgr->GetToolHolder() ) ) { - if( frame && copy ) + if( !( aCommitFlags & SKIP_UNDO ) ) { - frame->PushSymbolToUndoList( aMessage, copy ); - copy = nullptr; // we've transferred ownership to the undo stack + if( copy ) + { + frame->PushSymbolToUndoList( aMessage, copy ); + copy = nullptr; // we've transferred ownership to the undo stack + } } } @@ -171,17 +169,6 @@ void SCH_COMMIT::pushLibEdit( const wxString& aMessage, int aCommitFlags ) m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } ); m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified ); - - if( !( aCommitFlags & SKIP_SET_DIRTY ) ) - { - if( frame ) - frame->OnModify(); - } - - for( size_t ii = 1; ii < m_changes.size(); ++ii ) - delete m_changes[ii].m_copy; - - clear(); } @@ -452,14 +439,13 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) { if( frame ) { - frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity ); + frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false ); if( dirtyConnectivity ) { wxLogTrace( wxS( "CONN_PROFILE" ), wxS( "SCH_COMMIT::pushSchEdit() %s clean up connectivity rebuild." ), - ( connectivityCleanUp == LOCAL_CLEANUP ) ? wxS( "local" ) - : wxS( "global" ) ); + connectivityCleanUp == LOCAL_CLEANUP ? wxS( "local" ) : wxS( "global" ) ); frame->RecalculateConnections( this, connectivityCleanUp ); } } @@ -472,26 +458,29 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) if( selectedModified ) m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified ); - - if( frame && frame->GetCanvas() ) - frame->GetCanvas()->Refresh(); - - if( !( aCommitFlags & SKIP_SET_DIRTY ) ) - { - if( frame ) - frame->OnModify(); - } - - clear(); } void SCH_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) { + if( Empty() ) + return; + if( m_isLibEditor ) pushLibEdit( aMessage, aCommitFlags ); else pushSchEdit( aMessage, aCommitFlags ); + + if( SCH_BASE_FRAME* frame = static_cast( m_toolMgr->GetToolHolder() ) ) + { + if( !( aCommitFlags & SKIP_SET_DIRTY ) ) + frame->OnModify(); + + if( frame && frame->GetCanvas() ) + frame->GetCanvas()->Refresh(); + } + + clear(); } @@ -517,6 +506,7 @@ EDA_ITEM* SCH_COMMIT::makeImage( EDA_ITEM* aItem ) const LIB_SYMBOL* symbol = frame->GetCurSymbol(); std::vector selected; + // Cloning will clear the selected flags, but we want to keep them. for( const SCH_ITEM& item : symbol->GetDrawItems() ) { if( item.IsSelected() ) @@ -525,6 +515,7 @@ EDA_ITEM* SCH_COMMIT::makeImage( EDA_ITEM* aItem ) const symbol = new LIB_SYMBOL( *symbol ); + // Restore selected flags. for( SCH_ITEM& item : symbol->GetDrawItems() ) { if( alg::contains( selected, item.m_Uuid ) ) @@ -638,12 +629,15 @@ void SCH_COMMIT::Revert() if( unselect ) { item->ClearSelected(); - item->RunOnChildren( []( SCH_ITEM* aChild ) { aChild->ClearSelected(); }, RECURSE_MODE::NO_RECURSE ); + item->RunOnChildren( []( SCH_ITEM* aChild ) + { + aChild->ClearSelected(); + }, + RECURSE_MODE::NO_RECURSE ); } // Special cases for items which have instance data - if( item->GetParent() && item->GetParent()->Type() == SCH_SYMBOL_T - && item->Type() == SCH_FIELD_T ) + if( item->GetParent() && item->GetParent()->Type() == SCH_SYMBOL_T && item->Type() == SCH_FIELD_T ) { SCH_FIELD* field = static_cast( item ); SCH_SYMBOL* symbol = static_cast( item->GetParent() ); diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 6ad46fa2c1..1bececc1c2 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -293,6 +293,8 @@ public: void SetHighlightedConnection( const wxString& aConnection, const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr ); + void DirtyHighlightedConnection() { m_highlightedConnChanged = true; } + /** * Check if we are ready to write a netlist file for the current schematic. * @@ -622,10 +624,9 @@ public: * @param aItemToCopy is the schematic item modified by the command to undo. * @param aTypeCommand is the command type (see enum UNDO_REDO). * @param aAppend set to true to add the item to the previous undo list. - * @param aDirtyConnectivity set to true if the change can affect connectivity. */ void SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItemToCopy, UNDO_REDO aTypeCommand, - bool aAppend, bool aDirtyConnectivity = true ); + bool aAppend ); /** * Create a new entry in undo list of commands. @@ -633,10 +634,9 @@ public: * @param aItemsList is the list of items modified by the command to undo/ * @param aTypeCommand is the command type (see enum UNDO_REDO). * @param aAppend set to true to add the item to the previous undo list. - * @param aDirtyConnectivity set to true if the change can affect connectivity. */ void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO aTypeCommand, - bool aAppend, bool aDirtyConnectivity = true ); + bool aAppend ); /** * Restore an undo or redo command to put data pointed by \a aList in the previous state. diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 70e6badf36..c7ecb1d10f 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -42,22 +41,16 @@ /* Functions to undo and redo edit commands. * - * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST - * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER), - * that store the list of schematic items that are concerned by the command to - * undo or redo and is created for each command to undo (handle also a command - * to redo). each picker has a pointer pointing to an item to undo or redo (in - * fact: deleted, added or modified), and has a pointer to a copy of this item, - * when this item has been modified (the old values of parameters are - * therefore saved) + * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST. Each PICKED_ITEMS_LIST handles + * a std::vector of ITEM_PICKER that store the list of schematic items that are concerned by the command + * to undo or redo and is created for each command to undo/redo). Each picker has a pointer pointing to + * an item to undo or redo (in fact: deleted, added or modified), and has a pointer to a copy of this + * item, when this item has been modified (the old values of parameters are therefore saved). * * there are 3 cases: * - delete item(s) command * - change item(s) command * - add item(s) command - * and 2 cases for block: - * - move list of items - * - mirror (Y) list of items * * Undo command * - delete item(s) command: @@ -83,44 +76,18 @@ * => The list of item(s) is used to create a deleted list in undo * list(same as a delete command) * - * Some block operations that change items can be undone without memorized - * items, just the coordinates of the transform: move list of items (undo/ - * redo is made by moving with the opposite move vector) mirror (Y) and flip - * list of items (undo/redo is made by mirror or flip items) so they are - * handled specifically. - * - * A problem is the hierarchical sheet handling. - * the data associated (sub-hierarchy, undo/redo list) is deleted only - * when the sheet is really deleted (i.e. when deleted from undo or redo list) - * This is handled by its destructor. + * A problem is the hierarchical sheet handling. The data associated (sub-hierarchy, undo/redo list) is + * deleted only when the sheet is really deleted (i.e. when deleted from undo or redo list). This is + * handled by its destructor. */ - -/* Used if undo / redo command: - * swap data between Item and its copy, pointed by its picked item link member - * swapped data is data modified by editing, so not all values are swapped - */ - -void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, - UNDO_REDO aCommandType, bool aAppend, - bool aDirtyConnectivity ) +void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, UNDO_REDO aCommandType, + bool aAppend ) { PICKED_ITEMS_LIST* commandToUndo = nullptr; wxCHECK( aItem, /* void */ ); - if( aDirtyConnectivity ) - { - if( !aItem->IsConnectivityDirty() && aItem->Connection() - && ( aItem->Connection()->Name() == m_highlightedConn - || aItem->Connection()->HasDriverChanged() ) ) - { - m_highlightedConnChanged = true; - } - - aItem->SetConnectivityDirty(); - } - PICKED_ITEMS_LIST* lastUndo = PopCommandFromUndoList(); // If the last stack was empty, use that one instead of creating a new stack @@ -153,8 +120,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, break; default: - wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), - aCommandType ) ); + wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType ) ); break; } @@ -173,9 +139,8 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, } -void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, - UNDO_REDO aTypeCommand, bool aAppend, - bool aDirtyConnectivity ) +void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO aTypeCommand, + bool aAppend ) { PICKED_ITEMS_LIST* commandToUndo = nullptr; @@ -442,16 +407,16 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) wxCHECK2( origSheet && copySheet, continue ); - if( ( origSheet->GetName() != copySheet->GetName() ) - || ( origSheet->GetFileName() != copySheet->GetFileName() ) - || origSheet->HasPageNumberChanges( *copySheet ) ) + if( origSheet->GetName() != copySheet->GetName() + || origSheet->GetFileName() != copySheet->GetFileName() + || origSheet->HasPageNumberChanges( *copySheet ) ) { rebuildHierarchyNavigator = true; } // Sheet name changes do not require rebuilding the hiearchy. - if( ( origSheet->GetFileName() != copySheet->GetFileName() ) - || origSheet->HasPageNumberChanges( *copySheet ) ) + if( origSheet->GetFileName() != copySheet->GetFileName() + || origSheet->HasPageNumberChanges( *copySheet ) ) { refreshHierarchy = true; } @@ -484,8 +449,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) break; default: - wxFAIL_MSG( wxString::Format( wxT( "Unknown undo/redo command %d" ), - aList->GetPickedItemStatus( ii ) ) ); + wxFAIL_MSG( wxString::Format( wxT( "Unknown undo/redo command %d" ), status ) ); break; } @@ -546,9 +510,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) if( dirtyConnectivity ) { - wxLogTrace( wxS( "CONN_PROFILE" ), - wxS( "Undo/redo %s clean up connectivity rebuild." ), - ( connectivityCleanUp == LOCAL_CLEANUP ) ? wxS( "local" ) : wxS( "global" ) ); + wxLogTrace( wxS( "CONN_PROFILE" ), wxS( "Undo/redo %s clean up connectivity rebuild." ), + connectivityCleanUp == LOCAL_CLEANUP ? wxS( "local" ) : wxS( "global" ) ); SCH_COMMIT localCommit( m_toolManager ); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 0e909c7dbd..33fd1aa7aa 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -192,10 +192,10 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent ) undoCmd.PushItem( wrapper ); undoCmd.SetDescription( _( "Page Settings" ) ); - m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS, false, false ); + m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS, false ); - DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, m_frame->Schematic().GetEmbeddedFiles(), VECTOR2I( MAX_PAGE_SIZE_EESCHEMA_MILS, - MAX_PAGE_SIZE_EESCHEMA_MILS ) ); + DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, m_frame->Schematic().GetEmbeddedFiles(), + VECTOR2I( MAX_PAGE_SIZE_EESCHEMA_MILS, MAX_PAGE_SIZE_EESCHEMA_MILS ) ); dlg.SetWksFileName( BASE_SCREEN::m_DrawingSheetFileName ); if( dlg.ShowModal() == wxID_OK ) diff --git a/eeschema/tools/sch_tool_base.h b/eeschema/tools/sch_tool_base.h index 3436ad37ad..a4c548c5e9 100644 --- a/eeschema/tools/sch_tool_base.h +++ b/eeschema/tools/sch_tool_base.h @@ -22,8 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef SCH_TOOL_BASE_H -#define SCH_TOOL_BASE_H +#pragma once #include #include @@ -104,63 +103,46 @@ public: protected: /** - * Similar to getView()->Update(), but handles items that are redrawn by their parents - * and updating the SCH_SCREEN's RTree. + * Similar to getView()->Update(), but also updates the SCH_SCREEN's RTree. */ void updateItem( EDA_ITEM* aItem, bool aUpdateRTree ) const { m_frame->UpdateItem( aItem, false, aUpdateRTree ); } - ///< Similar to m_frame->SaveCopyInUndoList(), but handles items that are owned by their - ///< parents. - void saveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aType, bool aAppend = false, - bool aDirtyConnectivity = true ) + ///< Similar to m_frame->SaveCopyInUndoList(), but also handles connectivity. + void saveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aType, bool aAppend = false, bool aDirtyConnectivity = true ) { - wxASSERT( aItem ); + if( !aItem->IsSCH_ITEM() ) + return; - KICAD_T itemType = aItem->Type(); - bool selected = aItem->IsSelected(); + SCH_ITEM* item = static_cast( aItem ); + bool selected = item->IsSelected(); // IS_SELECTED flag should not be set on undo items which were added for // a drag operation. - if( selected && aItem->HasFlag( SELECTED_BY_DRAG ) ) - aItem->ClearSelected(); + if( selected && item->HasFlag( SELECTED_BY_DRAG ) ) + item->ClearSelected(); - if( m_isSymbolEditor ) + if( SYMBOL_EDIT_FRAME* symbolEditFrame = dynamic_cast( m_frame ) ) { - SYMBOL_EDIT_FRAME* editFrame = dynamic_cast( m_frame ); - wxCHECK_RET( editFrame, wxT( "editFrame is null" ) ); - - editFrame->SaveCopyInUndoList( wxEmptyString, dynamic_cast( aItem ) ); + symbolEditFrame->SaveCopyInUndoList( wxEmptyString, dynamic_cast( item ) ); } - else + else if( SCH_EDIT_FRAME* schematicFrame = dynamic_cast( m_frame ) ) { - SCH_EDIT_FRAME* editFrame = dynamic_cast( m_frame ); - wxASSERT( editFrame ); + schematicFrame->SaveCopyInUndoList( schematicFrame->GetScreen(), item, UNDO_REDO::CHANGED, aAppend ); - if( editFrame ) + if( aDirtyConnectivity ) { - if( itemType == SCH_FIELD_T ) + if( !item->IsConnectivityDirty() + && item->Connection() + && ( item->Connection()->Name() == schematicFrame->GetHighlightedConnection() + || item->Connection()->HasDriverChanged() ) ) { - editFrame->SaveCopyInUndoList( editFrame->GetScreen(), - static_cast( aItem->GetParent() ), - UNDO_REDO::CHANGED, aAppend, - false ); - } - else if( itemType == SCH_PIN_T || itemType == SCH_SHEET_PIN_T ) - { - editFrame->SaveCopyInUndoList( editFrame->GetScreen(), - static_cast( aItem->GetParent() ), - UNDO_REDO::CHANGED, aAppend, - aDirtyConnectivity ); - } - else - { - editFrame->SaveCopyInUndoList( editFrame->GetScreen(), - static_cast( aItem ), aType, - aAppend, aDirtyConnectivity ); + schematicFrame->DirtyHighlightedConnection(); } + + item->SetConnectivityDirty(); } } @@ -174,6 +156,3 @@ protected: SCH_SELECTION_TOOL* m_selectionTool; bool m_isSymbolEditor; }; - - -#endif