From 7340c97ef9ded8ad0ff9e1cf9547084c9ae3a711 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 13 Jul 2020 12:21:40 +0100 Subject: [PATCH] Undo for schematic-wide operations. Editing value/footprint fields of multi-unit components. Find/Change. Annotation. Back annotation. Fixes https://gitlab.com/kicad/code/kicad/issues/2122 Fixes https://gitlab.com/kicad/code/kicad/issues/4869 Fixes https://gitlab.com/kicad/code/kicad/issues/3933 Fixes https://gitlab.com/kicad/code/kicad/issues/4871 Fixes https://gitlab.com/kicad/code/kicad/issues/3899 --- common/base_screen.cpp | 50 -------- common/eda_base_frame.cpp | 54 +++++++- common/eda_draw_frame.cpp | 4 +- common/undo_redo_container.cpp | 31 +++++ cvpcb/display_footprints_frame.cpp | 11 -- eeschema/annotate.cpp | 64 ++++++---- eeschema/bus-wire-junction.cpp | 45 ++++--- eeschema/dialogs/dialog_annotate.cpp | 74 ++--------- eeschema/dialogs/dialog_annotate_base.cpp | 10 +- eeschema/dialogs/dialog_annotate_base.fbp | 8 +- eeschema/dialogs/dialog_annotate_base.h | 4 +- .../dialog_edit_component_in_schematic.cpp | 34 ++--- eeschema/dialogs/dialog_edit_label.cpp | 2 +- eeschema/dialogs/dialog_edit_line_style.cpp | 6 +- eeschema/dialogs/dialog_edit_one_field.cpp | 22 ++-- eeschema/dialogs/dialog_edit_sheet_pin.cpp | 5 +- .../dialogs/dialog_fields_editor_global.cpp | 4 +- .../dialog_global_edit_text_and_graphics.cpp | 2 +- eeschema/dialogs/dialog_junction_props.cpp | 6 +- eeschema/dialogs/dialog_sch_sheet_props.cpp | 2 +- eeschema/dialogs/dialog_symbol_remap.cpp | 2 +- eeschema/dialogs/dialog_update_fields.cpp | 47 ++++--- eeschema/dialogs/dialog_update_fields.h | 13 +- eeschema/files-io.cpp | 5 +- eeschema/getpart.cpp | 2 +- eeschema/hierarch.cpp | 1 - eeschema/invoke_sch_dialog.h | 4 +- eeschema/libedit/lib_edit_frame.cpp | 20 ++- eeschema/libedit/lib_edit_frame.h | 14 +++ eeschema/libedit/libedit.cpp | 2 +- eeschema/libedit/libedit_undo_redo.cpp | 34 ++--- eeschema/libedit/menubar_libedit.cpp | 4 +- eeschema/libedit/toolbars_libedit.cpp | 6 +- eeschema/menubar.cpp | 4 +- eeschema/sch_base_frame.h | 4 +- eeschema/sch_edit_frame.cpp | 27 ++-- eeschema/sch_edit_frame.h | 43 ++++--- eeschema/sch_screen.cpp | 23 ---- eeschema/sch_screen.h | 23 ---- eeschema/schematic_undo_redo.cpp | 53 ++++---- eeschema/sheet.cpp | 1 - eeschema/toolbars_sch_editor.cpp | 4 +- eeschema/tools/backannotate.cpp | 117 ++++++++---------- eeschema/tools/backannotate.h | 7 +- eeschema/tools/ee_tool_base.h | 13 +- eeschema/tools/sch_drawing_tools.cpp | 12 +- eeschema/tools/sch_edit_tool.cpp | 43 +++---- eeschema/tools/sch_editor_control.cpp | 20 +-- eeschema/tools/sch_line_wire_bus_tool.cpp | 23 ++-- eeschema/tools/sch_move_tool.cpp | 2 +- include/base_screen.h | 87 +------------ include/eda_base_frame.h | 95 +++++++++++++- include/eda_draw_frame.h | 2 - include/pcb_screen.h | 31 ----- include/undo_redo_container.h | 25 +++- pagelayout_editor/CMakeLists.txt | 1 - .../dialogs/dialogs_for_printing.cpp | 2 +- pagelayout_editor/menubar.cpp | 4 +- pagelayout_editor/pl_editor_frame.cpp | 61 +++++---- pagelayout_editor/pl_editor_frame.h | 15 ++- pagelayout_editor/pl_editor_screen.cpp | 67 ---------- pagelayout_editor/pl_editor_screen.h | 53 -------- pagelayout_editor/pl_editor_undo_redo.cpp | 36 +++--- pagelayout_editor/toolbars_pl_editor.cpp | 4 +- pagelayout_editor/tools/pl_editor_control.cpp | 2 +- pcbnew/board_commit.cpp | 10 +- pcbnew/class_board.cpp | 4 +- .../dialog_global_edit_tracks_and_vias.cpp | 2 +- pcbnew/edit_track_width.cpp | 2 +- pcbnew/footprint_edit_frame.cpp | 1 - pcbnew/footprint_libraries_utils.cpp | 2 +- pcbnew/initpcb.cpp | 4 +- pcbnew/load_select_footprint.cpp | 4 +- pcbnew/menubar_footprint_editor.cpp | 4 +- pcbnew/menubar_pcb_editor.cpp | 4 +- pcbnew/pcb_base_edit_frame.cpp | 5 +- pcbnew/pcb_base_edit_frame.h | 20 +++ pcbnew/pcb_edit_frame.cpp | 1 - pcbnew/pcb_screen.cpp | 6 - .../specctra_import.cpp | 2 +- pcbnew/swig/pcbnew_action_plugins.cpp | 36 +++--- pcbnew/toolbars_footprint_editor.cpp | 4 +- pcbnew/toolbars_pcb_editor.cpp | 4 +- pcbnew/tools/footprint_editor_tools.cpp | 5 +- pcbnew/tools/pcb_editor_control.cpp | 2 +- pcbnew/undo_redo.cpp | 24 ++-- pcbnew/zones_functions_for_undo_redo.cpp | 2 +- qa/qa_utils/mocks.cpp | 5 - 88 files changed, 768 insertions(+), 881 deletions(-) delete mode 100644 pagelayout_editor/pl_editor_screen.cpp delete mode 100644 pagelayout_editor/pl_editor_screen.h diff --git a/common/base_screen.cpp b/common/base_screen.cpp index de71a49be1..13e1dc3aaf 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -36,7 +36,6 @@ wxString BASE_SCREEN::m_PageLayoutDescrFileName; // the name of the page layou BASE_SCREEN::BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType ) : EDA_ITEM( aParent, aType ) { - m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS; m_Initialized = false; m_ScreenNumber = 1; m_NumberOfScreens = 1; // Hierarchy: Root: ScreenNumber = 1 @@ -70,55 +69,6 @@ void BASE_SCREEN::InitDataPoints( const wxSize& aPageSizeIU ) } -void BASE_SCREEN::ClearUndoRedoList() -{ - ClearUndoORRedoList( m_UndoList ); - ClearUndoORRedoList( m_RedoList ); -} - - -void BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem ) -{ - m_UndoList.PushCommand( aNewitem ); - - // Delete the extra items, if count max reached - if( m_UndoRedoCountMax > 0 ) - { - int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax; - - if( extraitems > 0 ) - ClearUndoORRedoList( m_UndoList, extraitems ); - } -} - - -void BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem ) -{ - m_RedoList.PushCommand( aNewitem ); - - // Delete the extra items, if count max reached - if( m_UndoRedoCountMax > 0 ) - { - int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax; - - if( extraitems > 0 ) - ClearUndoORRedoList( m_RedoList, extraitems ); - } -} - - -PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromUndoList( ) -{ - return m_UndoList.PopCommand(); -} - - -PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromRedoList( ) -{ - return m_RedoList.PopCommand(); -} - - #if defined(DEBUG) void BASE_SCREEN::Show( int nestLevel, std::ostream& os ) const diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index c331339ada..f33042afaa 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -81,6 +81,7 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, m_hasAutoSave( false ), m_autoSaveState( false ), m_autoSaveInterval(-1 ), + m_UndoRedoCountMax( DEFAULT_MAX_UNDO_ITEMS ), m_userUnits( EDA_UNITS::MILLIMETRES ) { m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER ); @@ -156,10 +157,10 @@ EDA_BASE_FRAME::~EDA_BASE_FRAME() delete m_autoSaveTimer; delete m_fileHistory; + ClearUndoRedoList(); + if( SupportsShutdownBlockReason() ) - { RemoveShutdownBlockReason(); - } } @@ -793,6 +794,55 @@ bool EDA_BASE_FRAME::IsContentModified() } +void EDA_BASE_FRAME::ClearUndoRedoList() +{ + ClearUndoORRedoList( m_UndoList ); + ClearUndoORRedoList( m_RedoList ); +} + + +void EDA_BASE_FRAME::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem ) +{ + m_UndoList.PushCommand( aNewitem ); + + // Delete the extra items, if count max reached + if( m_UndoRedoCountMax > 0 ) + { + int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax; + + if( extraitems > 0 ) + ClearUndoORRedoList( m_UndoList, extraitems ); + } +} + + +void EDA_BASE_FRAME::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem ) +{ + m_RedoList.PushCommand( aNewitem ); + + // Delete the extra items, if count max reached + if( m_UndoRedoCountMax > 0 ) + { + int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax; + + if( extraitems > 0 ) + ClearUndoORRedoList( m_RedoList, extraitems ); + } +} + + +PICKED_ITEMS_LIST* EDA_BASE_FRAME::PopCommandFromUndoList( ) +{ + return m_UndoList.PopCommand(); +} + + +PICKED_ITEMS_LIST* EDA_BASE_FRAME::PopCommandFromRedoList( ) +{ + return m_RedoList.PopCommand(); +} + + void EDA_BASE_FRAME::ChangeUserUnits( EDA_UNITS aUnits ) { SetUserUnits( aUnits ); diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index 34bbf79bba..5af0ad2618 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -570,9 +570,7 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg ) aCfg->m_System.units = static_cast( m_userUnits ); aCfg->m_System.first_run_shown = m_firstRunDialogSetting; - - if( GetScreen() ) - aCfg->m_System.max_undo_items = GetScreen()->GetMaxUndoItems(); + aCfg->m_System.max_undo_items = GetMaxUndoItems(); m_galDisplayOptions.WriteConfig( *window ); diff --git a/common/undo_redo_container.cpp b/common/undo_redo_container.cpp index a8a3ce1691..2723d63633 100644 --- a/common/undo_redo_container.cpp +++ b/common/undo_redo_container.cpp @@ -28,12 +28,34 @@ #include +/* ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus ) { m_undoRedoStatus = aUndoRedoStatus; SetItem( aItem ); m_pickerFlags = 0; + m_link = nullptr; + m_screen = nullptr; +} +*/ + +ITEM_PICKER::ITEM_PICKER() +{ + m_undoRedoStatus = UR_UNSPECIFIED; + SetItem( nullptr ); + m_pickerFlags = 0; m_link = NULL; + m_screen = nullptr; +} + + +ITEM_PICKER::ITEM_PICKER( BASE_SCREEN* aScreen, EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus ) +{ + m_undoRedoStatus = aUndoRedoStatus; + SetItem( aItem ); + m_pickerFlags = 0; + m_link = NULL; + m_screen = aScreen; } @@ -144,6 +166,15 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const } +BASE_SCREEN* PICKED_ITEMS_LIST::GetScreenForItem( unsigned int aIdx ) const +{ + if( aIdx < m_ItemsList.size() ) + return m_ItemsList[aIdx].GetScreen(); + + return NULL; +} + + EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const { if( aIdx < m_ItemsList.size() ) diff --git a/cvpcb/display_footprints_frame.cpp b/cvpcb/display_footprints_frame.cpp index 60edcaa7d6..266b34bc83 100644 --- a/cvpcb/display_footprints_frame.cpp +++ b/cvpcb/display_footprints_frame.cpp @@ -311,17 +311,6 @@ MAGNETIC_SETTINGS* DISPLAY_FOOTPRINTS_FRAME::GetMagneticItemsSettings() } -/** - * Virtual function needed by the PCB_SCREEN class derived from BASE_SCREEN - * this is a virtual pure function in BASE_SCREEN - * do nothing in Cvpcb - * could be removed later - */ -void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER&, int ) -{ -} - - COLOR4D DISPLAY_FOOTPRINTS_FRAME::GetGridColor() { return COLOR4D( DARKGRAY ); diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 13e032146a..5493e6d012 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -58,18 +58,34 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map& aMap ) } -void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly ) +void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly, bool* aAppendUndo ) { + auto clearAnnotation = + [&]( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aSheet ) + { + for( SCH_ITEM* item : aScreen->Items().OfType( SCH_COMPONENT_T ) ) + { + SCH_COMPONENT* component = static_cast( item ); + + SaveCopyInUndoList( aScreen, component, UR_CHANGED, *aAppendUndo ); + *aAppendUndo = true; + component->ClearAnnotation( aSheet ); + + // Clear the modified component flag set by component->ClearAnnotation + // because we do not use it here and we should not leave this flag set, + // when an editing is finished: + component->ClearFlags(); + } + }; + if( aCurrentSheetOnly ) { - SCH_SCREEN* screen = GetScreen(); - wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) ); - screen->ClearAnnotation( &GetCurrentSheet() ); + clearAnnotation( GetScreen(), &GetCurrentSheet() ); } else { - SCH_SCREENS ScreenList( Schematic().Root() ); - ScreenList.ClearAnnotation(); + for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() ) + clearAnnotation( sheet.LastScreen(), nullptr ); } // Update the references for the sheet that is currently being displayed. @@ -91,11 +107,9 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, REPORTER& aReporter ) { SCH_REFERENCE_LIST references; - - SCH_SCREENS screens( Schematic().Root() ); - - // Build the sheet list. - SCH_SHEET_LIST sheets = Schematic().GetSheets(); + SCH_SCREENS screens( Schematic().Root() ); + SCH_SHEET_LIST sheets = Schematic().GetSheets(); + bool appendUndo = false; // Map of locked components SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents; @@ -132,7 +146,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, // If it is an annotation for all the components, reset previous annotation. if( aResetAnnotation ) - DeleteAnnotation( !aAnnotateSchematic ); + DeleteAnnotation( !aAnnotateSchematic, &appendUndo ); // Set sheet number and number of sheets. SetSheetNumberAndCount(); @@ -175,21 +189,25 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, // Recalculate and update reference numbers in schematic references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents ); - references.UpdateAnnotation(); for( size_t i = 0; i < references.GetCount(); i++ ) { - SCH_COMPONENT* comp = references[ i ].GetComp(); - SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath(); - KIID_PATH curr_full_uuid = curr_sheetpath->Path(); - curr_full_uuid.push_back( comp->m_Uuid ); + SCH_REFERENCE& ref = references[i]; + SCH_COMPONENT* comp = ref.GetComp(); + SCH_SHEET_PATH* sheet = &ref.GetSheetPath(); - wxString prevRef = previousAnnotation[ curr_full_uuid.AsString() ]; + SaveCopyInUndoList( sheet->LastScreen(), comp, UR_CHANGED, appendUndo ); + appendUndo = true; + ref.Annotate(); - wxString newRef = comp->GetRef( curr_sheetpath ); + KIID_PATH full_uuid = sheet->Path(); + full_uuid.push_back( comp->m_Uuid ); + + wxString prevRef = previousAnnotation[ full_uuid.AsString() ]; + wxString newRef = comp->GetRef( sheet ); if( comp->GetUnitCount() > 1 ) - newRef << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) ); + newRef << LIB_PART::SubReference( comp->GetUnitSelection( sheet ) ); wxString msg; @@ -202,11 +220,13 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, msg.Printf( _( "Updated %s (unit %s) from %s to %s" ), comp->GetField( VALUE )->GetShownText(), LIB_PART::SubReference( comp->GetUnit(), false ), - prevRef, newRef ); + prevRef, + newRef ); else msg.Printf( _( "Updated %s from %s to %s" ), comp->GetField( VALUE )->GetShownText(), - prevRef, newRef ); + prevRef, + newRef ); } else { diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp index 4f5483f862..aa6a935227 100644 --- a/eeschema/bus-wire-junction.cpp +++ b/eeschema/bus-wire-junction.cpp @@ -84,12 +84,13 @@ bool SCH_EDIT_FRAME::TestDanglingEnds() bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd ) { - bool retval = false; + SCH_SCREEN* screen = GetScreen(); + bool retval = false; if( aStart == aEnd ) return retval; - for( auto item : GetScreen()->Items().OfType( SCH_LINE_T ) ) + for( EDA_ITEM* item : screen->Items().OfType( SCH_LINE_T ) ) { SCH_LINE* line = static_cast( item ); @@ -117,17 +118,19 @@ bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd ) // Ensure that *line points to the segment containing aEnd SCH_LINE* return_line = line; BreakSegment( line, aStart, &return_line ); + if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aEnd ) ) line = return_line; // Step 2: break the remaining segment. return_line remains line if not broken. // Ensure that *line _also_ contains aStart. This is our overlapping segment BreakSegment( line, aEnd, &return_line ); + if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aStart ) ) line = return_line; - SaveCopyInUndoList( line, UR_DELETED, true ); - RemoveFromScreen( line ); + SaveCopyInUndoList( screen, line, UR_DELETED, true ); + RemoveFromScreen( line, screen ); retval = true; } @@ -148,11 +151,12 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen ) if( aScreen == nullptr ) aScreen = GetScreen(); - auto remove_item = [&itemList, &deletedItems]( SCH_ITEM* aItem ) -> void { - aItem->SetFlags( STRUCT_DELETED ); - itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) ); - deletedItems.push_back( aItem ); - }; + auto remove_item = [&itemList, &deletedItems, &aScreen]( SCH_ITEM* aItem ) -> void + { + aItem->SetFlags( STRUCT_DELETED ); + itemList.PushItem( ITEM_PICKER( aScreen, aItem, UR_DELETED ) ); + deletedItems.push_back( aItem ); + }; BreakSegmentsOnJunctions( aScreen ); @@ -245,7 +249,7 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen ) { remove_item( firstLine ); remove_item( secondLine ); - itemList.PushItem( ITEM_PICKER( mergedLine, UR_NEW ) ); + itemList.PushItem( ITEM_PICKER( aScreen, mergedLine, UR_NEW ) ); AddToScreen( mergedLine, aScreen ); @@ -288,8 +292,8 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, newSegment->SetStartPoint( aPoint ); AddToScreen( newSegment, aScreen ); - SaveCopyInUndoList( newSegment, UR_NEW, true ); - SaveCopyInUndoList( aSegment, UR_CHANGED, true ); + SaveCopyInUndoList( aScreen, newSegment, UR_NEW, true ); + SaveCopyInUndoList( aScreen, aSegment, UR_CHANGED, true ); RefreshItem( aSegment ); aSegment->SetEndPoint( aPoint ); @@ -362,11 +366,11 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend ) auto remove_item = [ & ]( SCH_ITEM* aItem ) -> void { aItem->SetFlags( STRUCT_DELETED ); - undoList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) ); + undoList.PushItem( ITEM_PICKER( screen, aItem, UR_DELETED ) ); }; remove_item( aJunction ); - RemoveFromScreen( aJunction ); + RemoveFromScreen( 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 @@ -401,8 +405,8 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend ) { remove_item( firstLine ); remove_item( secondLine ); - undoList.PushItem( ITEM_PICKER( line, UR_NEW ) ); - AddToScreen( line ); + undoList.PushItem( ITEM_PICKER( screen, line, UR_NEW ) ); + AddToScreen( line, screen ); if( line->IsSelected() ) selectionTool->AddItemToSel( line, true /*quiet mode*/ ); @@ -421,18 +425,19 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend ) if( line->IsSelected() ) selectionTool->RemoveItemFromSel( line, true /*quiet mode*/ ); - RemoveFromScreen( line ); + RemoveFromScreen( line, screen ); } } } -SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPos, bool aUndoAppend, bool aFinal ) +SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( SCH_SCREEN* aScreen, const wxPoint& aPos, + bool aUndoAppend, bool aFinal ) { SCH_JUNCTION* junction = new SCH_JUNCTION( aPos ); - AddToScreen( junction ); - SaveCopyInUndoList( junction, UR_NEW, aUndoAppend ); + AddToScreen( junction, aScreen ); + SaveCopyInUndoList( aScreen, junction, UR_NEW, aUndoAppend ); BreakSegments( aPos ); if( aFinal ) diff --git a/eeschema/dialogs/dialog_annotate.cpp b/eeschema/dialogs/dialog_annotate.cpp index b99b598165..5006a1bd95 100644 --- a/eeschema/dialogs/dialog_annotate.cpp +++ b/eeschema/dialogs/dialog_annotate.cpp @@ -1,8 +1,3 @@ -/** - * @file dialog_annotate.cpp - * @brief Annotation dialog functions. - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * @@ -30,11 +25,8 @@ #include #include -#include #include #include - -#include #include #include #include @@ -59,7 +51,7 @@ private: /// Initialises member variables void InitValues(); - void OnClearAnnotationCmpClick( wxCommandEvent& event ) override; + void OnClearAnnotationClick( wxCommandEvent& event ) override; void OnCloseClick( wxCommandEvent& event ) override; void OnClose( wxCloseEvent& event ) override; void OnApplyClick( wxCommandEvent& event ) override; @@ -132,7 +124,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE() void DIALOG_ANNOTATE::InitValues() { - auto cfg = static_cast( Kiface().KifaceSettings() ); + EESCHEMA_SETTINGS* cfg = static_cast( Kiface().KifaceSettings() ); int option; // These are always reset to attempt to keep the user out of trouble... @@ -144,12 +136,8 @@ void DIALOG_ANNOTATE::InitValues() switch( option ) { default: - case 0: - m_rbSortBy_X_Position->SetValue( true ); - break; - case 1: - m_rbSortBy_Y_Position->SetValue( true ); - break; + case 0: m_rbSortBy_X_Position->SetValue( true ); break; + case 1: m_rbSortBy_Y_Position->SetValue( true ); break; } option = cfg->m_AnnotatePanel.method; @@ -157,15 +145,9 @@ void DIALOG_ANNOTATE::InitValues() switch( option ) { default: - case 0: - m_rbFirstFree->SetValue( true ); - break; - case 1: - m_rbSheetX100->SetValue( true ); - break; - case 2: - m_rbSheetX1000->SetValue( true ); - break; + case 0: m_rbFirstFree->SetValue( true ); break; + case 1: m_rbSheetX100->SetValue( true ); break; + case 2: m_rbSheetX1000->SetValue( true ); break; } m_textNumberAfter->SetValue( wxT( "0" ) ); @@ -194,26 +176,6 @@ void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event ) void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) { - wxString message; - - // Ask for confirmation of destructive actions. - if( GetResetItems() ) - { - if( GetLevel() ) - message += _( "Clear and annotate all of the symbols on the entire schematic?" ); - else - message += _( "Clear and annotate all of the symbols on the current sheet?" ); - - message += _( "\n\nThis operation will change the current annotation and cannot be undone." ); - - KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); - dlg.SetOKLabel( _( "Clear and Annotate" ) ); - dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - } - m_MessageWindow->Clear(); REPORTER& reporter = m_MessageWindow->Reporter(); m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message @@ -222,7 +184,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) (ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(), GetResetItems() , true, GetLockUnits(), reporter ); - m_MessageWindow->Flush( true ); // Now update to show all messages + m_MessageWindow->Flush( true ); // Now update to show all messages m_Parent->GetCanvas()->Refresh(); @@ -241,25 +203,11 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) } -void DIALOG_ANNOTATE::OnClearAnnotationCmpClick( wxCommandEvent& event ) +void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event ) { - wxString message; + bool appendUndo = false; - if( GetLevel() ) - message = _( "Clear the existing annotation for the entire schematic?" ); - else - message = _( "Clear the existing annotation for the current sheet?" ); - - message += _( "\n\nThis operation will clear the existing annotation and cannot be undone." ); - - KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); - dlg.SetOKLabel( _( "Clear Annotation" ) ); - dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - - m_Parent->DeleteAnnotation( !GetLevel() ); + m_Parent->DeleteAnnotation( !GetLevel(), &appendUndo ); m_btnClear->Enable( false ); } diff --git a/eeschema/dialogs/dialog_annotate_base.cpp b/eeschema/dialogs/dialog_annotate_base.cpp index b4c72089d5..c4efe29001 100644 --- a/eeschema/dialogs/dialog_annotate_base.cpp +++ b/eeschema/dialogs/dialog_annotate_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -35,10 +35,10 @@ DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, con fgSizer1->SetFlexibleDirection( wxBOTH ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - wxString m_rbScopeChoices[] = { _("Use the entire schematic"), _("Use the current page only") }; + wxString m_rbScopeChoices[] = { _("Entire schematic"), _("Current sheet only") }; int m_rbScopeNChoices = sizeof( m_rbScopeChoices ) / sizeof( wxString ); m_rbScope = new wxRadioBox( this, wxID_ANY, _("Scope:"), wxDefaultPosition, wxDefaultSize, m_rbScopeNChoices, m_rbScopeChoices, 1, wxRA_SPECIFY_COLS ); - m_rbScope->SetSelection( 0 ); + m_rbScope->SetSelection( 1 ); fgSizer1->Add( m_rbScope, 0, wxALL|wxEXPAND, 5 ); wxStaticBoxSizer* sbSizer1; @@ -148,7 +148,7 @@ DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, con // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) ); - m_btnClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this ); + m_btnClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationClick ), NULL, this ); m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCloseClick ), NULL, this ); m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this ); } @@ -157,7 +157,7 @@ DIALOG_ANNOTATE_BASE::~DIALOG_ANNOTATE_BASE() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) ); - m_btnClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this ); + m_btnClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationClick ), NULL, this ); m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCloseClick ), NULL, this ); m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this ); diff --git a/eeschema/dialogs/dialog_annotate_base.fbp b/eeschema/dialogs/dialog_annotate_base.fbp index 205bc62eb5..03f1765b43 100644 --- a/eeschema/dialogs/dialog_annotate_base.fbp +++ b/eeschema/dialogs/dialog_annotate_base.fbp @@ -14,7 +14,6 @@ dialog_annotate_base 1000 none - 1 dialog_annotate_base @@ -26,7 +25,6 @@ 1 1 UI - 0 0 0 @@ -165,7 +163,7 @@ 1 0 - "Use the entire schematic" "Use the current page only" + "Entire schematic" "Current sheet only" 1 1 @@ -197,7 +195,7 @@ 1 Resizable - 0 + 1 1 wxRA_SPECIFY_COLS @@ -1018,7 +1016,7 @@ - OnClearAnnotationCmpClick + OnClearAnnotationClick diff --git a/eeschema/dialogs/dialog_annotate_base.h b/eeschema/dialogs/dialog_annotate_base.h index 72238eda1d..f3f37b86c0 100644 --- a/eeschema/dialogs/dialog_annotate_base.h +++ b/eeschema/dialogs/dialog_annotate_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -69,7 +69,7 @@ class DIALOG_ANNOTATE_BASE : public DIALOG_SHIM // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnClearAnnotationCmpClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnClearAnnotationClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnCloseClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); } diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 7614e4d1b7..24a035736f 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -415,7 +415,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow() // save old cmp in undo list if not already in edit, or moving ... if( m_cmp->GetEditFlags() == 0 ) - GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED ); + GetParent()->SaveCopyInUndoList( currentScreen, m_cmp, UR_CHANGED, false ); // Save current flags which could be modified by next change settings STATUS_FLAGS flags = m_cmp->GetFlags(); @@ -525,19 +525,23 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow() // should be kept in sync in multi-unit parts. if( m_cmp->GetUnitCount() > 1 ) { - std::vector otherUnits; - - CollectOtherUnits( GetParent()->GetCurrentSheet(), m_cmp, &otherUnits ); - - for( SCH_COMPONENT* otherUnit : otherUnits ) + for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() ) { - GetParent()->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */); - otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() ); - otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() ); - otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() ); - otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() ); - otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() ); - GetParent()->RefreshItem( otherUnit ); + SCH_SCREEN* screen = sheet.LastScreen(); + std::vector otherUnits; + + CollectOtherUnits( sheet, m_cmp, &otherUnits ); + + for( SCH_COMPONENT* otherUnit : otherUnits ) + { + GetParent()->SaveCopyInUndoList( screen, otherUnit, UR_CHANGED, true /* append */); + otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() ); + otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() ); + otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() ); + otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() ); + otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() ); + GetParent()->RefreshItem( otherUnit ); + } } } @@ -725,9 +729,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFieldsFromLibrary( wxCommandEvent copy.SetLibSymbol( libSymbol->Flatten().release() ); // Update the requested fields in the component copy - std::list components; - components.push_back( © ); - InvokeDialogUpdateFields( GetParent(), components, false ); + InvokeDialogUpdateFields( GetParent(), ©, false ); wxGridTableMessage clear( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, m_fields->size() ); m_grid->ProcessTableMessage( clear ); diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp index 1d8e59e06a..00b8bb486c 100644 --- a/eeschema/dialogs/dialog_edit_label.cpp +++ b/eeschema/dialogs/dialog_edit_label.cpp @@ -395,7 +395,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow() /* save old text in undo list if not already in edit */ if( m_CurrentText->GetEditFlags() == 0 ) - m_Parent->SaveCopyInUndoList( m_CurrentText, UR_CHANGED ); + m_Parent->SaveCopyInUndoList( m_Parent->GetScreen(), m_CurrentText, UR_CHANGED, false ); m_Parent->GetCanvas()->Refresh(); diff --git a/eeschema/dialogs/dialog_edit_line_style.cpp b/eeschema/dialogs/dialog_edit_line_style.cpp index 33734f498e..232963765f 100644 --- a/eeschema/dialogs/dialog_edit_line_style.cpp +++ b/eeschema/dialogs/dialog_edit_line_style.cpp @@ -211,10 +211,10 @@ bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow() PICKED_ITEMS_LIST pickedItems; STROKE_PARAMS stroke; - for( auto& strokeItem : m_strokeItems ) - pickedItems.PushItem( ITEM_PICKER( strokeItem, UR_CHANGED ) ); + for( SCH_ITEM* strokeItem : m_strokeItems ) + pickedItems.PushItem( ITEM_PICKER( m_frame->GetScreen(), strokeItem, UR_CHANGED ) ); - m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED ); + m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED, false ); for( auto& strokeItem : m_strokeItems ) { diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp index 8caa18f79d..83b59393a6 100644 --- a/eeschema/dialogs/dialog_edit_one_field.cpp +++ b/eeschema/dialogs/dialog_edit_one_field.cpp @@ -405,22 +405,26 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aField->SetText( m_text ); updateText( aField ); - // The value, footprint and datasheet fields should be kept in sync in multi-unit - // parts. + // The value, footprint and datasheet fields should be kept in sync in multi-unit parts. // Of course the component must be annotated to collect other units. if( editFrame && parent && parent->Type() == SCH_COMPONENT_T && ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) ) { SCH_COMPONENT* thisUnit = static_cast( parent ); - std::vector otherUnits; - CollectOtherUnits( editFrame->GetCurrentSheet(), thisUnit, &otherUnits ); - - for( SCH_COMPONENT* otherUnit : otherUnits ) + for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() ) { - editFrame->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */); - otherUnit->GetField( fieldType )->SetText( m_text ); - editFrame->RefreshItem( otherUnit ); + SCH_SCREEN* screen = sheet.LastScreen(); + std::vector otherUnits; + + CollectOtherUnits( sheet, thisUnit, &otherUnits ); + + for( SCH_COMPONENT* otherUnit : otherUnits ) + { + editFrame->SaveCopyInUndoList( screen, otherUnit, UR_CHANGED, true /* append */); + otherUnit->GetField( fieldType )->SetText( m_text ); + editFrame->RefreshItem( otherUnit ); + } } } diff --git a/eeschema/dialogs/dialog_edit_sheet_pin.cpp b/eeschema/dialogs/dialog_edit_sheet_pin.cpp index 0d6a6b37b5..9a37504d17 100644 --- a/eeschema/dialogs/dialog_edit_sheet_pin.cpp +++ b/eeschema/dialogs/dialog_edit_sheet_pin.cpp @@ -97,7 +97,10 @@ bool DIALOG_EDIT_SHEET_PIN::TransferDataToWindow() bool DIALOG_EDIT_SHEET_PIN::TransferDataFromWindow() { if( !m_sheetPin->IsNew() ) - m_frame->SaveCopyInUndoList( (SCH_ITEM*) m_sheetPin->GetParent(), UR_CHANGED ); + { + SCH_SHEET* parentSheet = m_sheetPin->GetParent(); + m_frame->SaveCopyInUndoList( m_frame->GetScreen(), parentSheet, UR_CHANGED, false ); + } m_sheetPin->SetText( EscapeString( m_comboName->GetValue(), CTX_NETNAME ) ); // Currently, eeschema uses only the text width as text size, diff --git a/eeschema/dialogs/dialog_fields_editor_global.cpp b/eeschema/dialogs/dialog_fields_editor_global.cpp index 5a0f3b14b4..d59f1b02c2 100644 --- a/eeschema/dialogs/dialog_fields_editor_global.cpp +++ b/eeschema/dialogs/dialog_fields_editor_global.cpp @@ -600,9 +600,9 @@ public: for( unsigned i = 0; i < m_componentRefs.GetCount(); ++i ) { SCH_COMPONENT& comp = *m_componentRefs[i].GetComp(); + SCH_SCREEN* screen = m_componentRefs[i].GetSheetPath().LastScreen(); - m_frame->SetCurrentSheet( m_componentRefs[i].GetSheetPath() ); - m_frame->SaveCopyInUndoList( &comp, UR_CHANGED, true ); + m_frame->SaveCopyInUndoList( screen, &comp, UR_CHANGED, true ); const std::map& fieldStore = m_dataStore[comp.m_Uuid]; diff --git a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp index 68cf499a0d..a52870afe2 100644 --- a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp +++ b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp @@ -218,7 +218,7 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aS auto sch_text = dynamic_cast( aItem ); auto lineItem = dynamic_cast( aItem ); - m_parent->SaveCopyInUndoList( aItem, UR_CHANGED, m_hasChange ); + m_parent->SaveCopyInUndoList( aSheetPath.LastScreen(), aItem, UR_CHANGED, m_hasChange ); if( eda_text ) { diff --git a/eeschema/dialogs/dialog_junction_props.cpp b/eeschema/dialogs/dialog_junction_props.cpp index 1bdc6b2483..5c86175d95 100644 --- a/eeschema/dialogs/dialog_junction_props.cpp +++ b/eeschema/dialogs/dialog_junction_props.cpp @@ -171,10 +171,10 @@ bool DIALOG_JUNCTION_PROPS::TransferDataFromWindow() { PICKED_ITEMS_LIST pickedItems; - for( auto& junction : m_junctions ) - pickedItems.PushItem( ITEM_PICKER( junction, UR_CHANGED ) ); + for( SCH_JUNCTION* junction : m_junctions ) + pickedItems.PushItem( ITEM_PICKER( m_frame->GetScreen(), junction, UR_CHANGED ) ); - m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED ); + m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED, false ); for( auto& junction : m_junctions ) { diff --git a/eeschema/dialogs/dialog_sch_sheet_props.cpp b/eeschema/dialogs/dialog_sch_sheet_props.cpp index 7f5276a925..4744f69e97 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props.cpp +++ b/eeschema/dialogs/dialog_sch_sheet_props.cpp @@ -481,7 +481,7 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam } if( isUndoable ) - m_frame->SaveCopyInUndoList( m_sheet, UR_CHANGED ); + m_frame->SaveCopyInUndoList( m_frame->GetScreen(), m_sheet, UR_CHANGED, false ); if( renameFile ) { diff --git a/eeschema/dialogs/dialog_symbol_remap.cpp b/eeschema/dialogs/dialog_symbol_remap.cpp index 6d647501dd..41f2dc8478 100644 --- a/eeschema/dialogs/dialog_symbol_remap.cpp +++ b/eeschema/dialogs/dialog_symbol_remap.cpp @@ -99,7 +99,7 @@ void DIALOG_SYMBOL_REMAP::OnRemapSymbols( wxCommandEvent& aEvent ) if( viewer ) viewer->ReCreateListLib(); - parent->GetScreen()->ClearUndoORRedoList( parent->GetScreen()->m_UndoList, 1 ); + parent->ClearUndoORRedoList( parent->m_UndoList, 1 ); parent->SyncView(); parent->GetCanvas()->Refresh(); parent->OnModify(); diff --git a/eeschema/dialogs/dialog_update_fields.cpp b/eeschema/dialogs/dialog_update_fields.cpp index 3669dffff5..7ab923e345 100644 --- a/eeschema/dialogs/dialog_update_fields.cpp +++ b/eeschema/dialogs/dialog_update_fields.cpp @@ -28,23 +28,41 @@ #include #include +#include #include #include -int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, - const list aComponents, bool aCreateUndoEntry ) +int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, SCH_COMPONENT* aSpecificComponent, + bool aCreateUndoEntry ) { - DIALOG_UPDATE_FIELDS dlg( aCaller, aComponents, aCreateUndoEntry ); + DIALOG_UPDATE_FIELDS dlg( aCaller, aSpecificComponent, aCreateUndoEntry ); return dlg.ShowQuasiModal(); } DIALOG_UPDATE_FIELDS::DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, - const list& aComponents, bool aCreateUndoEntry ) - : DIALOG_UPDATE_FIELDS_BASE( aParent ), m_frame( aParent ), - m_components( aComponents ), m_createUndo( aCreateUndoEntry ) + SCH_COMPONENT* aSpecificComponent, + bool aCreateUndoEntry ) : + DIALOG_UPDATE_FIELDS_BASE( aParent ), + m_frame( aParent ), + m_createUndo( aCreateUndoEntry ) { + if( aSpecificComponent ) + { + m_components.emplace_back( aParent->GetScreen(), aSpecificComponent ); + } + else + { + for( SCH_SHEET_PATH& path : aParent->Schematic().GetSheets() ) + { + SCH_SCREEN* screen = path.LastScreen(); + + for( SCH_ITEM* item : screen->Items().OfType( SCH_COMPONENT_T ) ) + m_components.emplace_back( screen, static_cast( item ) ); + } + } + m_sdbSizerOK->SetDefault(); } @@ -57,7 +75,6 @@ bool DIALOG_UPDATE_FIELDS::TransferDataFromWindow() if( m_components.empty() ) return true; // nothing to process - // Create the set of fields to be updated m_updateFields.clear(); @@ -73,16 +90,16 @@ bool DIALOG_UPDATE_FIELDS::TransferDataFromWindow() { PICKED_ITEMS_LIST itemsList; - for( auto component : m_components ) - itemsList.PushItem( ITEM_PICKER( component, UR_CHANGED ) ); + for( std::pair& component : m_components ) + itemsList.PushItem( ITEM_PICKER( component.first, component.second, UR_CHANGED ) ); - m_frame->SaveCopyInUndoList( itemsList, UR_CHANGED ); + m_frame->SaveCopyInUndoList( itemsList, UR_CHANGED, true ); } // Do it! - for( auto component : m_components ) - updateFields( component ); + for( std::pair& component : m_components ) + updateFields( component.second ); m_frame->SyncView(); m_frame->GetCanvas()->Refresh(); @@ -99,9 +116,9 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow() // Collect all user field names from library parts of components that are going to be updated { - for( auto component : m_components ) + for( std::pair& component : m_components ) { - const std::unique_ptr< LIB_PART >& part = component->GetPartRef(); + const std::unique_ptr< LIB_PART >& part = component.second->GetPartRef(); if( !part ) continue; @@ -123,7 +140,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow() for( int i = 0; i < MANDATORY_FIELDS; ++i ) { - m_fieldsBox->Append( m_components.front()->GetField( i )->GetName() ); + m_fieldsBox->Append( m_components.front().second->GetField( i )->GetName() ); if( i != REFERENCE && i != VALUE ) m_fieldsBox->Check( i, true ); diff --git a/eeschema/dialogs/dialog_update_fields.h b/eeschema/dialogs/dialog_update_fields.h index ff4bd209f3..bad6eb1940 100644 --- a/eeschema/dialogs/dialog_update_fields.h +++ b/eeschema/dialogs/dialog_update_fields.h @@ -34,17 +34,14 @@ class SCH_COMPONENT; class SCH_SCREEN; class SCH_EDIT_FRAME; -using std::set; -using std::list; - /** * Dialog to update component fields (i.e. restore them from the original library symbols). */ class DIALOG_UPDATE_FIELDS : public DIALOG_UPDATE_FIELDS_BASE { public: - DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, const list& aComponents, - bool aCreateUndoEntry = true ); + DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, SCH_COMPONENT* aComponent, + bool aCreateUndoEntry ); private: bool TransferDataFromWindow() override; @@ -66,16 +63,14 @@ private: checkAll( false ); } - ///> Parent frame SCH_EDIT_FRAME* m_frame; ///> Set of field names that should have values updated - set m_updateFields; + std::set m_updateFields; ///> Components to update - list m_components; + std::vector< std::pair> m_components; - ///> Flag indicating whether an undo buffer entry should be created bool m_createUndo; }; diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index a98492bd5d..cf8cf7165a 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -492,7 +492,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet. RecalculateConnections( GLOBAL_CLEANUP ); - GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 ); + ClearUndoRedoList(); GetScreen()->m_Initialized = true; } @@ -872,10 +872,11 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) } } } + // Only perform the dangling end test on root sheet. GetScreen()->TestDanglingEnds(); - GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 ); + ClearUndoRedoList(); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); SetSheetNumberAndCount(); diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 92127b3693..3ee2828ca1 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -211,7 +211,7 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_COMPONENT* aComponent, int aUnit ) STATUS_FLAGS savedFlags = aComponent->GetFlags(); if( !aComponent->GetEditFlags() ) // No command in progress: save in undo list - SaveCopyInUndoList( aComponent, UR_CHANGED ); + SaveCopyInUndoList( GetScreen(), aComponent, UR_CHANGED, false ); /* Update the unit number. */ aComponent->SetUnitSelection( &GetCurrentSheet(), aUnit ); diff --git a/eeschema/hierarch.cpp b/eeschema/hierarch.cpp index 123bd82ddf..ae122c6df9 100644 --- a/eeschema/hierarch.cpp +++ b/eeschema/hierarch.cpp @@ -245,7 +245,6 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet() { m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); screen->m_Initialized = true; - screen->ClearUndoORRedoList( screen->m_UndoList, 1 ); } else { diff --git a/eeschema/invoke_sch_dialog.h b/eeschema/invoke_sch_dialog.h index 2113f1a157..7c50877115 100644 --- a/eeschema/invoke_sch_dialog.h +++ b/eeschema/invoke_sch_dialog.h @@ -86,8 +86,8 @@ int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller ); void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller ); /// Update symbol fields -int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, - const std::list aComponents, bool aCreateUndoEntry ); +int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, SCH_COMPONENT* aSpecificComponent = nullptr, + bool aCreateUndoEntry = true ); /** * Create and shows NETLIST_DIALOG and returns whatever diff --git a/eeschema/libedit/lib_edit_frame.cpp b/eeschema/libedit/lib_edit_frame.cpp index 3747f6ef4b..ab523e7f08 100644 --- a/eeschema/libedit/lib_edit_frame.cpp +++ b/eeschema/libedit/lib_edit_frame.cpp @@ -117,7 +117,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_dummyScreen = new SCH_SCREEN(); SetScreen( m_dummyScreen ); GetScreen()->m_Center = true; - GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false ); @@ -726,7 +725,7 @@ void LIB_EDIT_FRAME::emptyScreen() SetCurLib( wxEmptyString ); SetCurPart( nullptr ); SetScreen( m_dummyScreen ); - m_dummyScreen->ClearUndoRedoList(); + ClearUndoRedoList(); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); Refresh(); } @@ -909,3 +908,20 @@ bool LIB_EDIT_FRAME::IsContentModified() return false; } + + +void LIB_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) +{ + if( aItemCount == 0 ) + return; + + for( auto& command : aList.m_CommandsList ) + { + command->ClearListAndDeleteItems(); + delete command; + } + + aList.m_CommandsList.clear(); +} + + diff --git a/eeschema/libedit/lib_edit_frame.h b/eeschema/libedit/lib_edit_frame.h index 8b4c568378..6fb9041dbf 100644 --- a/eeschema/libedit/lib_edit_frame.h +++ b/eeschema/libedit/lib_edit_frame.h @@ -342,6 +342,20 @@ public: void RollbackPartFromUndo(); + /** + * Free the undo or redo list from \a aList element. + * + * - Wrappers are deleted. + * - data pointed by wrappers are deleted if not in use in schematic + * i.e. when they are copy of a schematic item or they are no more in use (DELETED) + * + * @param aList = the UNDO_REDO_CONTAINER to clear + * @param aItemCount = the count of items to remove. < 0 for all items + * items are removed from the beginning of the list. + * So this function can be called to remove old commands + */ + void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; + private: /** * Read a component symbol file (*.sym ) and add graphic items to the current component. diff --git a/eeschema/libedit/libedit.cpp b/eeschema/libedit/libedit.cpp index c3758efaf0..3afdb8ea57 100644 --- a/eeschema/libedit/libedit.cpp +++ b/eeschema/libedit/libedit.cpp @@ -186,7 +186,7 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, in // Enable synchronized pin edit mode for symbols with interchangeable units m_SyncPinEdit = !GetCurPart()->UnitsLocked(); - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() ); diff --git a/eeschema/libedit/libedit_undo_redo.cpp b/eeschema/libedit/libedit_undo_redo.cpp index 752194300e..6d31517d1a 100644 --- a/eeschema/libedit/libedit_undo_redo.cpp +++ b/eeschema/libedit/libedit_undo_redo.cpp @@ -41,34 +41,34 @@ void LIB_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* ItemToCopy, UNDO_REDO_T undoT if( !ItemToCopy ) return; - LIB_PART* CopyItem; + LIB_PART* copyItem; PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); - CopyItem = new LIB_PART( * (LIB_PART*) ItemToCopy ); + copyItem = new LIB_PART( * (LIB_PART*) ItemToCopy ); // Clear current flags (which can be temporary set by a current edit command). - CopyItem->ClearTempFlags(); - CopyItem->ClearEditFlags(); - CopyItem->SetFlags( UR_TRANSIENT ); + copyItem->ClearTempFlags(); + copyItem->ClearEditFlags(); + copyItem->SetFlags( UR_TRANSIENT ); - ITEM_PICKER wrapper( CopyItem, undoType ); + ITEM_PICKER wrapper( GetScreen(), copyItem, undoType ); lastcmd->PushItem( wrapper ); - GetScreen()->PushCommandToUndoList( lastcmd ); + PushCommandToUndoList( lastcmd ); // Clear redo list, because after new save there is no redo to do. - GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); + ClearUndoORRedoList( m_RedoList ); } void LIB_EDIT_FRAME::GetComponentFromRedoList() { - if( GetScreen()->GetRedoCommandCount() <= 0 ) + if( GetRedoCommandCount() <= 0 ) return; m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); // Load the last redo entry - PICKED_ITEMS_LIST* redoCommand = GetScreen()->PopCommandFromRedoList(); + PICKED_ITEMS_LIST* redoCommand = PopCommandFromRedoList(); ITEM_PICKER redoWrapper = redoCommand->PopItem(); delete redoCommand; LIB_PART* part = (LIB_PART*) redoWrapper.GetItem(); @@ -80,9 +80,9 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList() PICKED_ITEMS_LIST* undoCommand = new PICKED_ITEMS_LIST(); LIB_PART* oldPart = m_my_part; oldPart->SetFlags( UR_TRANSIENT ); - ITEM_PICKER undoWrapper( oldPart, undoRedoType ); + ITEM_PICKER undoWrapper( GetScreen(), oldPart, undoRedoType ); undoCommand->PushItem( undoWrapper ); - GetScreen()->PushCommandToUndoList( undoCommand ); + PushCommandToUndoList( undoCommand ); // Do not delete the previous part by calling SetCurPart( part ) // which calls delete . @@ -110,13 +110,13 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList() void LIB_EDIT_FRAME::GetComponentFromUndoList() { - if( GetScreen()->GetUndoCommandCount() <= 0 ) + if( GetUndoCommandCount() <= 0 ) return; m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); // Load the last undo entry - PICKED_ITEMS_LIST* undoCommand = GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* undoCommand = PopCommandFromUndoList(); ITEM_PICKER undoWrapper = undoCommand->PopItem(); delete undoCommand; LIB_PART* part = (LIB_PART*) undoWrapper.GetItem(); @@ -128,9 +128,9 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList() PICKED_ITEMS_LIST* redoCommand = new PICKED_ITEMS_LIST(); LIB_PART* oldPart = m_my_part; oldPart->SetFlags( UR_TRANSIENT ); - ITEM_PICKER redoWrapper( oldPart, undoRedoType ); + ITEM_PICKER redoWrapper( GetScreen(), oldPart, undoRedoType ); redoCommand->PushItem( redoWrapper ); - GetScreen()->PushCommandToRedoList( redoCommand ); + PushCommandToRedoList( redoCommand ); // Do not delete the previous part by calling SetCurPart( part ), // which calls delete . @@ -161,7 +161,7 @@ void LIB_EDIT_FRAME::RollbackPartFromUndo() m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); // Load the last undo entry - PICKED_ITEMS_LIST* undoCommand = GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* undoCommand = PopCommandFromUndoList(); // Check if we were already at the top of the stack if( !undoCommand ) diff --git a/eeschema/libedit/menubar_libedit.cpp b/eeschema/libedit/menubar_libedit.cpp index ef4d82f583..8ddf7d59e1 100644 --- a/eeschema/libedit/menubar_libedit.cpp +++ b/eeschema/libedit/menubar_libedit.cpp @@ -95,10 +95,10 @@ void LIB_EDIT_FRAME::ReCreateMenuBar() CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { - return m_my_part && GetScreen() && GetScreen()->GetUndoCommandCount() != 0; + return m_my_part && GetUndoCommandCount() != 0; }; auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { - return m_my_part && GetScreen() && GetScreen()->GetRedoCommandCount() != 0; + return m_my_part && GetRedoCommandCount() != 0; }; auto haveSymbolCondition = [ this ] ( const SELECTION& sel ) { return m_my_part != nullptr; diff --git a/eeschema/libedit/toolbars_libedit.cpp b/eeschema/libedit/toolbars_libedit.cpp index 1083456be9..68d007e429 100644 --- a/eeschema/libedit/toolbars_libedit.cpp +++ b/eeschema/libedit/toolbars_libedit.cpp @@ -158,10 +158,8 @@ void LIB_EDIT_FRAME::SyncToolbars() bool isEditable = m_my_part && m_my_part->IsRoot(); m_mainToolBar->Toggle( ACTIONS::saveAll, m_libMgr->HasModifications() ); - m_mainToolBar->Toggle( ACTIONS::undo, - GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, - GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) ); m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, (bool) m_my_part ); m_mainToolBar->Toggle( EE_ACTIONS::runERC, isEditable ); diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 16147b5f9f..559332e00f 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -132,10 +132,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; + return GetUndoCommandCount() > 0; }; auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; + return GetRedoCommandCount() > 0; }; editMenu->AddItem( ACTIONS::undo, enableUndoCondition ); diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h index f4d2b2a82a..9712c7a13a 100644 --- a/eeschema/sch_base_frame.h +++ b/eeschema/sch_base_frame.h @@ -249,13 +249,13 @@ public: * Add an item to the screen (and view) * aScreen is the screen the item is located on, if not the current screen */ - void AddToScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen = nullptr ); + void AddToScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen ); /** * Remove an item from the screen (and view) * aScreen is the screen the item is located on, if not the current screen */ - void RemoveFromScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen = nullptr ); + void RemoveFromScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen ); /** * Mark an item for refresh. diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 4fbfe99994..81e41a9f61 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -424,7 +424,6 @@ void SCH_EDIT_FRAME::CreateScreens() m_defaults = &m_schematic->Settings(); SCH_SCREEN* rootScreen = new SCH_SCREEN( m_schematic ); - rootScreen->SetMaxUndoItems( m_UndoRedoCountMax ); m_schematic->Root().SetScreen( rootScreen ); SetScreen( Schematic().RootScreen() ); @@ -433,7 +432,6 @@ void SCH_EDIT_FRAME::CreateScreens() if( GetScreen() == NULL ) { SCH_SCREEN* screen = new SCH_SCREEN( m_schematic ); - screen->SetMaxUndoItems( m_UndoRedoCountMax ); SetScreen( screen ); } } @@ -891,10 +889,9 @@ bool SCH_EDIT_FRAME::isAutoSaveRequired() const } -void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppend ) +void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, + bool aUndoAppend ) { - SCH_SCREEN* screen = GetScreen(); - wxCHECK_RET( aItem != NULL, wxT( "Cannot add null item to list." ) ); SCH_SHEET* parentSheet = nullptr; @@ -926,7 +923,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe if( aItem->Type() == SCH_SHEET_PIN_T ) { // Sheet pins are owned by their parent sheet. - SaveCopyInUndoList( undoItem, UR_CHANGED, aUndoAppend ); // save the parent sheet + SaveCopyInUndoList( aScreen, undoItem, UR_CHANGED, aUndoAppend ); parentSheet->AddPin( (SCH_SHEET_PIN*) aItem ); } @@ -938,11 +935,11 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe } else { - if( !screen->CheckIfOnDrawList( aItem ) ) // don't want a loop! - AddToScreen( aItem ); + if( !aScreen->CheckIfOnDrawList( aItem ) ) // don't want a loop! + AddToScreen( aItem, aScreen ); SaveCopyForRepeatItem( aItem ); - SaveCopyInUndoList( undoItem, UR_NEW, aUndoAppend ); + SaveCopyInUndoList( aScreen, undoItem, UR_NEW, aUndoAppend ); } // Update connectivity info for new item @@ -952,7 +949,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe aItem->ClearFlags( IS_NEW ); - screen->SetModify(); + aScreen->SetModify(); RefreshItem( aItem ); if( !aItem->IsMoving() && aItem->IsConnectable() ) @@ -965,8 +962,8 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe for( auto j = i + 1; j != pts.end(); j++ ) TrimWire( *i, *j ); - if( screen->IsJunctionNeeded( *i, true ) ) - AddJunction( *i, true, false ); + if( aScreen->IsJunctionNeeded( *i, true ) ) + AddJunction( aScreen, *i, true, false ); } TestDanglingEnds(); @@ -1104,7 +1101,7 @@ void SCH_EDIT_FRAME::FixupJunctions() SetCurrentSheet( sheet ); GetCurrentSheet().UpdateAllScreenReferences(); - auto screen = GetCurrentSheet().LastScreen(); + SCH_SCREEN* screen = GetCurrentSheet().LastScreen(); for( auto aItem : screen->Items().OfType( SCH_COMPONENT_T ) ) { @@ -1120,8 +1117,8 @@ void SCH_EDIT_FRAME::FixupJunctions() } } - for( auto& pos : junctions ) - AddJunction( pos, false, false ); + for( const wxPoint& pos : junctions ) + AddJunction( screen, pos, false, false ); if( junctions.size() ) modified = true; diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 52a257c093..f7d088b388 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -259,7 +259,7 @@ public: * 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. */ - void AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppend = false ); + void AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, bool aUndoAppend ); /** * Run the Find or Find & Replace dialog. @@ -423,7 +423,7 @@ public: * @param aCurrentSheetOnly Clear only the annotation for the current sheet if true. * Otherwise clear the entire schematic annotation. */ - void DeleteAnnotation( bool aCurrentSheetOnly ); + void DeleteAnnotation( bool aCurrentSheetOnly, bool* appendUndo ); /** * Annotate the components in the schematic that are not currently annotated. @@ -572,7 +572,7 @@ public: */ bool AskToSaveChanges(); - SCH_JUNCTION* AddJunction( const wxPoint& aPos, bool aAppendToUndo = false, + SCH_JUNCTION* AddJunction( SCH_SCREEN* aScreen, const wxPoint& aPos, bool aAppendToUndo, bool aFinal = true ); /** @@ -792,7 +792,7 @@ public: /** * Create a copy of the current schematic item, and put it in the undo list. * - * flag_type_command = + * aTypeCommand = * UR_CHANGED * UR_NEW * UR_DELETED @@ -804,21 +804,19 @@ public: * * @note * Edit wires and buses is a bit complex. - * because when a new wire is added, a lot of modifications in wire list is made - * (wire concatenation): modified items, deleted items and new items - * so flag_type_command is UR_WIRE_IMAGE: the struct ItemToCopy is a list of - * wires saved in Undo List (for Undo or Redo commands, saved wires will be - * exchanged with current wire list + * When a new wire is added, a lot of modifications are made in the wire list (merging, + * junctions, etc.). We therefore set the aTypeCommand to UR_WIRE_IMAGE and save the whole + * schebang. * * @param aItemToCopy = the schematic item modified by the command to undo * @param aTypeCommand = command type (see enum UNDO_REDO_T) * @param aAppend = add the item to the previous undo list - * @param aTransformPoint = the reference point of the transformation, - * for commands like move + * @param aTransformPoint = the reference point of the transformation for commands like move */ - void SaveCopyInUndoList( SCH_ITEM* aItemToCopy, + void SaveCopyInUndoList( SCH_SCREEN* aScreen, + SCH_ITEM* aItemToCopy, UNDO_REDO_T aTypeCommand, - bool aAppend = false, + bool aAppend, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); /** @@ -827,12 +825,11 @@ public: * @param aItemsList = the list of items modified by the command to undo * @param aTypeCommand = command type (see enum UNDO_REDO_T) * @param aAppend = add the item to the previous undo list - * @param aTransformPoint = the reference point of the transformation, - * for commands like move + * @param aTransformPoint = the reference point of the transformation for commands like move */ void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, - bool aAppend = false, + bool aAppend, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); /** @@ -843,6 +840,20 @@ public: */ void PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand ); + /** + * Free the undo or redo list from \a aList element. + * + * - Wrappers are deleted. + * - data pointed by wrappers are deleted if not in use in schematic + * i.e. when they are copy of a schematic item or they are no more in use (DELETED) + * + * @param aList = the UNDO_REDO_CONTAINER to clear + * @param aItemCount = the count of items to remove. < 0 for all items + * items are removed from the beginning of the list. + * So this function can be called to remove old commands + */ + void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; + /** * Clone \a aItem and owns that clone in this container. */ diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index cfb65eb98e..bee11c2883 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -85,7 +85,6 @@ SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) : SCH_SCREEN::~SCH_SCREEN() { clearLibSymbols(); - ClearUndoRedoList(); FreeDrawList(); } @@ -801,21 +800,6 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) } -void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) -{ - if( aItemCount == 0 ) - return; - - for( auto& command : aList.m_CommandsList ) - { - command->ClearListAndDeleteItems(); - delete command; - } - - aList.m_CommandsList.clear(); -} - - void SCH_SCREEN::ClearDrawingState() { for( auto item : Items() ) @@ -1230,13 +1214,6 @@ void SCH_SCREENS::buildScreenList( SCH_SHEET* aSheet ) } -void SCH_SCREENS::ClearAnnotation() -{ - for( SCH_SCREEN* screen : m_screens ) - screen->ClearAnnotation( NULL ); -} - - void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList ) { SCH_SCREEN* first = GetFirst(); diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 763540b487..3b13b833c5 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -330,24 +330,6 @@ public: */ std::set MarkConnections( SCH_LINE* aSegment ); - /* full undo redo management : */ - // use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ) - // use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ) - - /** - * Free the undo or redo list from \a aList element. - * - * - Wrappers are deleted. - * - data pointed by wrappers are deleted if not in use in schematic - * i.e. when they are copy of a schematic item or they are no more in use (DELETED) - * - * @param aList = the UNDO_REDO_CONTAINER to clear - * @param aItemCount = the count of items to remove. < 0 for all items - * items are removed from the beginning of the list. - * So this function can be called to remove old commands - */ - virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; - /** * Clear the state flags of all the items in the screen. */ @@ -560,11 +542,6 @@ public: SCH_SCREEN* GetScreen( unsigned int aIndex ) const; SCH_SHEET* GetSheet( unsigned int aIndex ) const; - /** - * Clear the annotation for all components in the hierarchy. - */ - void ClearAnnotation(); - /** * Clear the annotation for the components inside new sheetpaths * when a complex hierarchy is modified and new sheetpaths added diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 3177187001..efac143376 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -23,26 +23,17 @@ */ #include -#include #include #include -#include #include -#include #include #include -#include -#include -#include #include -#include #include #include #include /* Functions to undo and redo edit commands. - * commands to undo are stored in CurrentScreen->m_UndoList - * commands to redo are stored in CurrentScreen->m_RedoList * * 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), @@ -103,7 +94,8 @@ * swapped data is data modified by editing, so not all values are swapped */ -void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, +void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, + SCH_ITEM* aItem, UNDO_REDO_T aCommandType, bool aAppend, const wxPoint& aTransformPoint ) @@ -117,7 +109,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, aItem->SetConnectivityDirty(); if( aAppend ) - commandToUndo = GetScreen()->PopCommandFromUndoList(); + commandToUndo = PopCommandFromUndoList(); if( !commandToUndo ) { @@ -125,7 +117,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, commandToUndo->m_TransformPoint = aTransformPoint; } - ITEM_PICKER itemWrapper( aItem, aCommandType ); + ITEM_PICKER itemWrapper( aScreen, aItem, aCommandType ); itemWrapper.SetFlags( aItem->GetFlags() ); switch( aCommandType ) @@ -151,10 +143,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ - GetScreen()->PushCommandToUndoList( commandToUndo ); + PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after new save there is no redo to do */ - GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); + ClearUndoORRedoList( m_RedoList ); } else { @@ -175,7 +167,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, // Can't append a WIRE IMAGE, so fail to a new undo point if( aAppend ) - commandToUndo = GetScreen()->PopCommandFromUndoList(); + commandToUndo = PopCommandFromUndoList(); if( !commandToUndo ) { @@ -247,10 +239,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ - GetScreen()->PushCommandToUndoList( commandToUndo ); + PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after new save there is no redo to do */ - GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); + ClearUndoORRedoList( m_RedoList ); } else // Should not occur { @@ -275,13 +267,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed if( status == UR_NEW ) { // new items are deleted on undo - RemoveFromScreen( eda_item ); + RemoveFromScreen( eda_item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); aList->SetPickedItemStatus( UR_DELETED, (unsigned) ii ); } else if( status == UR_DELETED ) { // deleted items are re-inserted on undo - AddToScreen( eda_item ); + AddToScreen( eda_item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); aList->SetPickedItemStatus( UR_NEW, (unsigned) ii ); } else if( status == UR_PAGESETTINGS ) @@ -299,7 +291,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed SCH_ITEM* item = (SCH_ITEM*) eda_item; SCH_ITEM* alt_item = (SCH_ITEM*) aList->GetPickedItemLink( (unsigned) ii ); - RemoveFromScreen( item ); + RemoveFromScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); switch( status ) { @@ -343,7 +335,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed break; } - AddToScreen( item ); + AddToScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); } } @@ -359,7 +351,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed void SCH_EDIT_FRAME::RollbackSchematicFromUndo() { - PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* undo = PopCommandFromUndoList(); if( undo ) { @@ -375,3 +367,20 @@ void SCH_EDIT_FRAME::RollbackSchematicFromUndo() SyncView(); GetCanvas()->Refresh(); } + + +void SCH_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) +{ + if( aItemCount == 0 ) + return; + + for( auto& command : aList.m_CommandsList ) + { + command->ClearListAndDeleteItems(); + delete command; + } + + aList.m_CommandsList.clear(); +} + + diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 2e55b237d2..e0ac23acc0 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -96,7 +96,6 @@ void SCH_EDIT_FRAME::InitSheet( SCH_SHEET* aSheet, const wxString& aNewFilename { aSheet->SetScreen( new SCH_SCREEN( &Schematic() ) ); aSheet->GetScreen()->SetModify(); - aSheet->GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); aSheet->GetScreen()->SetFileName( aNewFilename ); } diff --git a/eeschema/toolbars_sch_editor.cpp b/eeschema/toolbars_sch_editor.cpp index 12f4093173..8ced412cad 100644 --- a/eeschema/toolbars_sch_editor.cpp +++ b/eeschema/toolbars_sch_editor.cpp @@ -172,8 +172,8 @@ void SCH_EDIT_FRAME::SyncToolbars() m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); - m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); m_mainToolBar->Refresh(); diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index b92ea48a0a..48b457a3f6 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -47,7 +47,8 @@ BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, m_ignoreOtherProjects( aIgnoreOtherProjects ), m_dryRun( aDryRun ), m_frame( aFrame ), - m_changesCount( 0 ) + m_changesCount( 0 ), + m_appendUndo( false ) { } @@ -60,6 +61,7 @@ BACK_ANNOTATE::~BACK_ANNOTATE() bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist ) { m_changesCount = 0; + m_appendUndo = false; wxString msg; if( !m_processValues && !m_processFootprints && !m_processReferences && !m_processNetNames ) @@ -79,9 +81,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist ) checkForUnusedSymbols(); checkSharedSchematicErrors(); - SCH_SHEET_PATH current = m_frame->GetCurrentSheet(); applyChangelist(); - m_frame->SetCurrentSheet( current ); return true; } @@ -280,12 +280,6 @@ bool BACK_ANNOTATE::checkReuseViolation( PCB_MODULE_DATA& aFirst, PCB_MODULE_DAT return true; } -wxString BACK_ANNOTATE::getTextFromField( const SCH_REFERENCE& aRef, const NumFieldType aField ) -{ - return aRef.GetComp()->GetField( aField )->GetText(); -} - - void BACK_ANNOTATE::checkSharedSchematicErrors() { std::sort( m_changelist.begin(), m_changelist.end(), @@ -334,9 +328,10 @@ void BACK_ANNOTATE::checkSharedSchematicErrors() means that this particular component is reused in some other project. */ if( !m_ignoreOtherProjects && compUsage > usageCount ) { + SCH_COMPONENT* comp = it->first.GetComp(); PCB_MODULE_DATA tmp{ "", - getTextFromField( it->first, FOOTPRINT ), - getTextFromField( it->first, VALUE ), + comp->GetField( FOOTPRINT )->GetText(), + comp->GetField( VALUE )->GetText(), {} }; if( !checkReuseViolation( tmp, *it->second ) ) @@ -360,16 +355,16 @@ void BACK_ANNOTATE::applyChangelist() { std::set handledNetChanges; wxString msg; - int leftUnchanged = 0; // Apply changes from change list for( CHANGELIST_ITEM& item : m_changelist ) { SCH_REFERENCE& ref = item.first; PCB_MODULE_DATA& module = *item.second; - wxString oldFootprint = getTextFromField( ref, FOOTPRINT ); - wxString oldValue = getTextFromField( ref, VALUE ); - int changesCountBefore = m_changesCount; + SCH_COMPONENT* comp = ref.GetComp(); + SCH_SCREEN* screen = ref.GetSheetPath().LastScreen(); + wxString oldFootprint = comp->GetField( FOOTPRINT )->GetText(); + wxString oldValue = comp->GetField( VALUE )->GetText(); bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0; if( m_processReferences && ref.GetRef() != module.m_ref && !skip ) @@ -380,7 +375,11 @@ void BACK_ANNOTATE::applyChangelist() module.m_ref ); if( !m_dryRun ) - ref.GetComp()->SetRef( &ref.GetSheetPath(), module.m_ref ); + { + m_frame->SaveCopyInUndoList( screen, comp, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; + comp->SetRef( &ref.GetSheetPath(), module.m_ref ); + } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); } @@ -390,11 +389,15 @@ void BACK_ANNOTATE::applyChangelist() ++m_changesCount; msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ), ref.GetFullRef(), - getTextFromField( ref, FOOTPRINT ), + comp->GetField( FOOTPRINT )->GetText(), module.m_footprint ); if( !m_dryRun ) + { + m_frame->SaveCopyInUndoList( screen, comp, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint ); + } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); } @@ -404,11 +407,15 @@ void BACK_ANNOTATE::applyChangelist() ++m_changesCount; msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ), ref.GetFullRef(), - getTextFromField( ref, VALUE ), + comp->GetField( VALUE )->GetText(), module.m_value ); if( !m_dryRun ) - item.first.GetComp()->GetField( VALUE )->SetText( module.m_value ); + { + m_frame->SaveCopyInUndoList( screen, comp, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; + comp->GetField( VALUE )->SetText( module.m_value ); + } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); } @@ -419,7 +426,6 @@ void BACK_ANNOTATE::applyChangelist() { const wxString& pinNumber = entry.first; const wxString& shortNetName = entry.second; - SCH_COMPONENT* comp = ref.GetComp(); LIB_PIN* pin = comp->GetPin( pinNumber ); SCH_CONNECTION* conn = comp->GetConnectionForPin( pin, ref.GetSheetPath() ); @@ -434,11 +440,8 @@ void BACK_ANNOTATE::applyChangelist() processNetNameChange( conn, conn->Name( true ), shortNetName ); } } - - if( changesCountBefore == m_changesCount ) - ++leftUnchanged; } - msg.Printf( _( "%d symbols left unchanged" ), leftUnchanged ); + m_reporter.ReportHead( msg, RPT_SEVERITY_INFO ); } @@ -459,7 +462,8 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& if( EscapeString( label->GetShownText(), CTX_NETNAME ) == oldName ) { - m_frame->SaveCopyInUndoList( label, UR_CHANGED ); + m_frame->SaveCopyInUndoList( aScreen, label, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; static_cast( label )->SetText( newName ); } } @@ -469,21 +473,20 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& { case SCH_LABEL_T: ++m_changesCount; - msg.Printf( _( "Change \"%s\" labels to \"%s\"." ), - aOldName, - aNewName ); + msg.Printf( _( "Change \"%s\" labels to \"%s\"." ), aOldName, aNewName ); if( !m_dryRun ) { - m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); + SCH_SCREEN* screen = aConn->Sheet().LastScreen(); - for( SCH_ITEM* label : m_frame->GetScreen()->Items().OfType( SCH_LABEL_T ) ) + for( SCH_ITEM* label : screen->Items().OfType( SCH_LABEL_T ) ) { SCH_CONNECTION* conn = label->Connection( aConn->Sheet() ); if( conn && conn->Driver() == driver ) { - m_frame->SaveCopyInUndoList( label, UR_CHANGED ); + m_frame->SaveCopyInUndoList( screen, label, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; static_cast( label )->SetText( aNewName ); } } @@ -494,19 +497,12 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& case SCH_GLOBAL_LABEL_T: ++m_changesCount; - msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ), - aConn->Name( true ), - aNewName ); + msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ), aOldName, aNewName ); if( !m_dryRun ) { - SCH_SHEET_LIST all_sheets = m_frame->Schematic().GetSheets(); - - for( const SCH_SHEET_PATH& sheet : all_sheets ) - { - m_frame->Schematic().SetCurrentSheet( sheet ); - editMatchingLabels( m_frame->GetScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName ); - } + for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().GetSheets() ) + editMatchingLabels( sheet.LastScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName ); } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); @@ -514,23 +510,22 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& case SCH_HIER_LABEL_T: ++m_changesCount; - msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), - aConn->Name( true ), - aNewName ); + msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), aOldName, aNewName ); if( !m_dryRun ) { - m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); - editMatchingLabels( m_frame->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName ); + SCH_SCREEN* screen = aConn->Sheet().LastScreen(); + editMatchingLabels( screen, SCH_HIER_LABEL_T, aOldName, aNewName ); - SCH_SHEET* sheet = dynamic_cast( driver->GetParent() ); - m_frame->SetScreen( sheet->GetScreen() ); + SCH_SHEET* sheet = dynamic_cast( driver->GetParent() ); + screen = sheet->GetScreen(); for( SCH_SHEET_PIN* pin : sheet->GetPins() ) { if( EscapeString( pin->GetShownText(), CTX_NETNAME ) == aOldName ) { - m_frame->SaveCopyInUndoList( pin, UR_CHANGED ); + m_frame->SaveCopyInUndoList( screen, pin, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; static_cast( pin )->SetText( aNewName ); } } @@ -541,19 +536,18 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& case SCH_SHEET_PIN_T: ++m_changesCount; - msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), - aConn->Name( true ), - aNewName ); + msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), aOldName, aNewName ); if( !m_dryRun ) { - m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); - m_frame->SaveCopyInUndoList( driver, UR_CHANGED ); + SCH_SCREEN* screen = aConn->Sheet().LastScreen(); + m_frame->SaveCopyInUndoList( screen, driver, UR_CHANGED, m_appendUndo ); + m_appendUndo = true; static_cast( driver )->SetText( aNewName ); SCH_SHEET* sheet = static_cast( driver )->GetParent(); - m_frame->SetScreen( sheet->GetScreen() ); - editMatchingLabels( sheet->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName ); + screen = sheet->GetScreen(); + editMatchingLabels( screen, SCH_HIER_LABEL_T, aOldName, aNewName ); } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); @@ -584,9 +578,7 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& } ++m_changesCount; - msg.Printf( _( "Add label \"%s\" to net \"%s\"." ), - aNewName, - aConn->Name( true ) ); + msg.Printf( _( "Add label \"%s\" to net \"%s\"." ), aNewName, aOldName ); if( !m_dryRun ) { @@ -598,8 +590,9 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& label->SetLabelSpinStyle( spin ); label->SetFlags( IS_NEW ); - m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); - m_frame->AddItemToScreenAndUndoList( label ); + SCH_SCREEN* screen = aConn->Sheet().LastScreen(); + m_frame->AddItemToScreenAndUndoList( screen, label, m_appendUndo ); + m_appendUndo = true; } m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); @@ -609,6 +602,4 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& default: break; } - - m_frame->Schematic().SetCurrentSheet( SCH_SHEET_PATH() ); } \ No newline at end of file diff --git a/eeschema/tools/backannotate.h b/eeschema/tools/backannotate.h index 28c6d19478..fbcd8cebab 100644 --- a/eeschema/tools/backannotate.h +++ b/eeschema/tools/backannotate.h @@ -115,11 +115,8 @@ private: std::deque m_changelist; SCH_EDIT_FRAME* m_frame; - ///> To count number of changes applied to the schematic - int m_changesCount; - - ///> Get text from symbol's field ( such as Footprint or Value ) - wxString getTextFromField( const SCH_REFERENCE& aRef, const NumFieldType aField ); + int m_changesCount; // Number of user-level changes + bool m_appendUndo; /** * @brief Check if modules has different data. Check only if corresponding \ref m_boardAdapter diff --git a/eeschema/tools/ee_tool_base.h b/eeschema/tools/ee_tool_base.h index 9595f6bfcb..64cd181949 100644 --- a/eeschema/tools/ee_tool_base.h +++ b/eeschema/tools/ee_tool_base.h @@ -137,10 +137,17 @@ protected: wxASSERT( editFrame ); if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T ) - editFrame->SaveCopyInUndoList( - static_cast( aItem->GetParent() ), UR_CHANGED, aAppend ); + { + editFrame->SaveCopyInUndoList( editFrame->GetScreen(), + static_cast( aItem->GetParent() ), + UR_CHANGED, aAppend ); + } else - editFrame->SaveCopyInUndoList( static_cast( aItem ), aType, aAppend ); + { + editFrame->SaveCopyInUndoList( editFrame->GetScreen(), + static_cast( aItem ), + aType, aAppend ); + } } if( selected && aItem->HasFlag( TEMP_SELECTED ) ) diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index b11cfd0665..804cdad1c3 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -191,7 +191,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) SCH_COMPONENT* next_comp = nullptr; m_view->ClearPreview(); - m_frame->AddItemToScreenAndUndoList( component ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), component, false ); EE_SELECTION new_sel; new_sel.Add( component ); @@ -388,7 +388,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) } else { - m_frame->AddItemToScreenAndUndoList( image ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), image, false ); image = nullptr; m_toolMgr->RunAction( ACTIONS::activatePointEditor ); @@ -510,14 +510,14 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) if( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) ) { if( type == SCH_JUNCTION_T ) - m_frame->AddJunction( cursorPos ); + m_frame->AddJunction( m_frame->GetScreen(), cursorPos, false ); else { SCH_ITEM* newItem = static_cast( previewItem->Clone() ); newItem->SetPosition( cursorPos ); newItem->SetFlags( IS_NEW ); - m_frame->AddItemToScreenAndUndoList( newItem ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), newItem, false ); m_frame->SaveCopyForRepeatItem( newItem ); m_frame->SchematicCleanUp(); @@ -855,7 +855,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) else { item->ClearFlags( IS_MOVED ); - m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, false ); item = getNextNewText(); if( item ) @@ -1007,7 +1007,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) { sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); - m_frame->AddItemToScreenAndUndoList( sheet ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), sheet, false ); m_frame->UpdateHierarchyNavigator(); m_selectionTool->AddItemToSel( sheet ); } diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 466df2a8ac..902d3ba9de 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -810,7 +810,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) case SCH_HIER_LABEL_T: case SCH_NO_CONNECT_T: newItem->SetParent( m_frame->GetScreen() ); - m_frame->AddToScreen( newItem ); + m_frame->AddToScreen( newItem, m_frame->GetScreen() ); break; case SCH_SHEET_T: @@ -828,7 +828,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) nameField.SetText( candidateName ); sheet->SetParent( m_frame->GetCurrentSheet().Last() ); - m_frame->AddToScreen( sheet ); + m_frame->AddToScreen( sheet, m_frame->GetScreen() ); copiedSheets = true; break; @@ -839,7 +839,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) SCH_COMPONENT* component = (SCH_COMPONENT*) newItem; component->ClearAnnotation( NULL ); component->SetParent( m_frame->GetScreen() ); - m_frame->AddToScreen( component ); + m_frame->AddToScreen( component, m_frame->GetScreen() ); break; } @@ -916,8 +916,8 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent ) } newItem->SetFlags( IS_NEW ); - m_frame->AddToScreen( newItem ); - m_frame->SaveCopyInUndoList( newItem, UR_NEW ); + m_frame->AddToScreen( newItem, m_frame->GetScreen() ); + m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UR_NEW, false ); m_selectionTool->AddItemToSel( newItem ); @@ -1011,7 +1011,9 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent ) sheet->RemovePin( pin ); } else - m_frame->RemoveFromScreen( sch_item ); + { + m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() ); + } if( sch_item->Type() == SCH_SHEET_T ) m_frame->UpdateHierarchyNavigator(); @@ -1121,7 +1123,7 @@ void SCH_EDIT_TOOL::editFieldText( SCH_FIELD* aField ) { // Save old component in undo list if not already in edit, or moving. if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved - m_frame->SaveCopyInUndoList( (SCH_ITEM*) aField->GetParent(), UR_CHANGED ); + saveCopyInUndoList( aField, UR_CHANGED ); wxString title = wxString::Format( _( "Edit %s Field" ), aField->GetName() ); @@ -1198,7 +1200,7 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent ) SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front(); if( !component->IsNew() ) - m_frame->SaveCopyInUndoList( component, UR_CHANGED ); + saveCopyInUndoList( component, UR_CHANGED ); component->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true ); @@ -1215,12 +1217,7 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent ) int SCH_EDIT_TOOL::UpdateFields( const TOOL_EVENT& aEvent ) { - std::list components; - - for( auto item : m_frame->GetScreen()->Items().OfType( SCH_COMPONENT_T ) ) - components.push_back( static_cast( item ) ); - - if( InvokeDialogUpdateFields( m_frame, components, true ) == wxID_OK ) + if( InvokeDialogUpdateFields( m_frame ) == wxID_OK ) m_frame->GetCanvas()->Refresh(); return 0; @@ -1245,7 +1242,7 @@ int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent ) return 0; if( !component->IsNew() ) - m_frame->SaveCopyInUndoList( component, UR_CHANGED ); + saveCopyInUndoList( component, UR_CHANGED ); m_frame->ConvertPart( component ); @@ -1290,7 +1287,7 @@ int SCH_EDIT_TOOL::RefreshSymbolFromLibrary( const TOOL_EVENT& aEvent ) if( !symbol->IsNew() ) { - m_frame->SaveCopyInUndoList( symbol, UR_CHANGED, appendToUndo ); + saveCopyInUndoList( symbol, UR_CHANGED, appendToUndo ); appendToUndo = true; } @@ -1473,7 +1470,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { // save old image in undo list if not already in edit if( bitmap->GetEditFlags() == 0 ) - m_frame->SaveCopyInUndoList( bitmap, UR_CHANGED ); + saveCopyInUndoList( bitmap, UR_CHANGED ); dlg.TransferToImage( bitmap->GetImage() ); @@ -1613,11 +1610,11 @@ int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent ) if( !text->IsNew() ) { - m_frame->SaveCopyInUndoList( text, UR_DELETED ); - m_frame->SaveCopyInUndoList( newtext, UR_NEW, true ); + saveCopyInUndoList( text, UR_DELETED ); + saveCopyInUndoList( newtext, UR_NEW, true ); - m_frame->RemoveFromScreen( text ); - m_frame->AddToScreen( newtext ); + m_frame->RemoveFromScreen( text, m_frame->GetScreen() ); + m_frame->AddToScreen( newtext, m_frame->GetScreen() ); } if( selected ) @@ -1656,7 +1653,7 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent ) if( m_frame->BreakSegments( cursorPos ) ) { if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) ) - m_frame->AddJunction( cursorPos, true, false ); + m_frame->AddJunction( m_frame->GetScreen(), cursorPos, true, false ); m_frame->TestDanglingEnds(); @@ -1685,7 +1682,7 @@ int SCH_EDIT_TOOL::CleanupSheetPins( const TOOL_EVENT& aEvent ) if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) ) return 0; - m_frame->SaveCopyInUndoList( sheet, UR_CHANGED ); + saveCopyInUndoList( sheet, UR_CHANGED ); sheet->CleanupSheet(); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 40d7780dbc..9833943d4f 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -100,10 +100,10 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent ) { PICKED_ITEMS_LIST undoCmd; WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( m_frame ); - ITEM_PICKER wrapper( undoItem, UR_PAGESETTINGS ); + ITEM_PICKER wrapper( m_frame->GetScreen(), undoItem, UR_PAGESETTINGS ); undoCmd.PushItem( wrapper ); - m_frame->SaveCopyInUndoList( undoCmd, UR_PAGESETTINGS ); + m_frame->SaveCopyInUndoList( undoCmd, UR_PAGESETTINGS, false ); DIALOG_PAGES_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) ); dlg.SetWksFileName( BASE_SCREEN::m_PageLayoutDescrFileName ); @@ -167,7 +167,7 @@ bool SCH_EDITOR_CONTROL::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand m_frame->RecalculateConnections( GLOBAL_CLEANUP ); } - m_frame->GetScreen()->ClearUndoORRedoList( m_frame->GetScreen()->m_UndoList, 1 ); + m_frame->ClearUndoRedoList(); m_frame->SyncView(); m_frame->GetCanvas()->Refresh(); m_frame->OnModify(); @@ -1160,21 +1160,21 @@ int SCH_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::Undo( const TOOL_EVENT& aEvent ) { - if( m_frame->GetScreen()->GetUndoCommandCount() <= 0 ) + if( m_frame->GetUndoCommandCount() <= 0 ) return 0; // Inform tools that undo command was issued m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); /* Get the old list */ - PICKED_ITEMS_LIST* List = m_frame->GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* List = m_frame->PopCommandFromUndoList(); /* Undo the command */ m_frame->PutDataInPreviousState( List, false ); /* Put the old list in RedoList */ List->ReversePickersListOrder(); - m_frame->GetScreen()->PushCommandToRedoList( List ); + m_frame->PushCommandToRedoList( List ); EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); selTool->RebuildSelection(); @@ -1192,21 +1192,21 @@ int SCH_EDITOR_CONTROL::Undo( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::Redo( const TOOL_EVENT& aEvent ) { - if( m_frame->GetScreen()->GetRedoCommandCount() == 0 ) + if( m_frame->GetRedoCommandCount() == 0 ) return 0; // Inform tools that undo command was issued m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); /* Get the old list */ - PICKED_ITEMS_LIST* List = m_frame->GetScreen()->PopCommandFromRedoList(); + PICKED_ITEMS_LIST* List = m_frame->PopCommandFromRedoList(); /* Redo the command: */ m_frame->PutDataInPreviousState( List, true ); /* Put the old list in UndoList */ List->ReversePickersListOrder(); - m_frame->GetScreen()->PushCommandToUndoList( List ); + m_frame->PushCommandToUndoList( List ); EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); selTool->RebuildSelection(); @@ -1495,7 +1495,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) } item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED ); - m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item, i > 0 ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, i > 0 ); // Reset flags for subsequent move operation item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 444d1eeccc..4ac25199b0 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -376,7 +376,7 @@ SCH_LINE* SCH_LINE_WIRE_BUS_TOOL::doUnfoldBus( const wxString& aNet ) m_busUnfold.entry = new SCH_BUS_WIRE_ENTRY( pos ); m_busUnfold.entry->SetParent( m_frame->GetScreen() ); - m_frame->AddToScreen( m_busUnfold.entry ); + m_frame->AddToScreen( m_busUnfold.entry, m_frame->GetScreen() ); m_busUnfold.label = new SCH_LABEL( m_busUnfold.entry->m_End(), aNet ); m_busUnfold.label->SetTextSize( wxSize( cfg.m_DefaultTextSize, cfg.m_DefaultTextSize ) ); @@ -512,13 +512,13 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType segment = nullptr; if( m_busUnfold.entry ) - m_frame->RemoveFromScreen( m_busUnfold.entry ); + m_frame->RemoveFromScreen( m_busUnfold.entry, screen ); if( m_busUnfold.label && !m_busUnfold.label_placed ) m_selectionTool->RemoveItemFromSel( m_busUnfold.label, true ); if( m_busUnfold.label && m_busUnfold.label_placed ) - m_frame->RemoveFromScreen( m_busUnfold.label ); + m_frame->RemoveFromScreen( m_busUnfold.label, screen ); delete m_busUnfold.entry; delete m_busUnfold.label; @@ -578,7 +578,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType { wxASSERT( aType == LAYER_WIRE ); - m_frame->AddToScreen( m_busUnfold.label ); + m_frame->AddToScreen( m_busUnfold.label, screen ); m_selectionTool->RemoveItemFromSel( m_busUnfold.label, true ); m_busUnfold.label_placed = true; } @@ -808,6 +808,7 @@ 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; // Remove segments backtracking over others @@ -831,15 +832,15 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments() if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), i ) ) new_ends.push_back( i ); } - itemList.PushItem( ITEM_PICKER( wire, UR_NEW ) ); + itemList.PushItem( ITEM_PICKER( screen, wire, UR_NEW ) ); } if( m_busUnfold.in_progress && m_busUnfold.label_placed ) { wxASSERT( m_busUnfold.entry && m_busUnfold.label ); - itemList.PushItem( ITEM_PICKER( m_busUnfold.entry, UR_NEW ) ); - itemList.PushItem( ITEM_PICKER( m_busUnfold.label, UR_NEW ) ); + itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.entry, UR_NEW ) ); + itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.label, UR_NEW ) ); m_busUnfold.label->ClearEditFlags(); } @@ -851,7 +852,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments() for( auto wire : m_wires ) { wire->ClearFlags( IS_NEW | IS_MOVED ); - m_frame->AddToScreen( wire ); + m_frame->AddToScreen( wire, screen ); } m_wires.clear(); @@ -861,7 +862,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments() getViewControls()->CaptureCursor( false ); getViewControls()->SetAutoPan( false ); - m_frame->SaveCopyInUndoList( itemList, UR_NEW ); + m_frame->SaveCopyInUndoList( itemList, UR_NEW, false ); // Correct and remove segments that need to be merged. m_frame->SchematicCleanUp(); @@ -884,7 +885,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments() for( auto i : new_ends ) { if( m_frame->GetScreen()->IsJunctionNeeded( i, true ) ) - m_frame->AddJunction( i, true, false ); + m_frame->AddJunction( m_frame->GetScreen(), i, true, false ); } if( m_busUnfold.in_progress ) @@ -949,7 +950,7 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent ) for( auto point : pts ) { if( m_frame->GetScreen()->IsJunctionNeeded( point, true ) ) - m_frame->AddJunction( point, true, false ); + m_frame->AddJunction( m_frame->GetScreen(), point, true, false ); } return 0; diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 6beab50686..0e514945e3 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -470,7 +470,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) for( auto it : internalPoints ) { if( m_frame->GetScreen()->IsJunctionNeeded( it.GetPosition(), true ) ) - m_frame->AddJunction( it.GetPosition(), true, false ); + m_frame->AddJunction( m_frame->GetScreen(), it.GetPosition(), true, false ); } m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection ); diff --git a/include/base_screen.h b/include/base_screen.h index c9c7e11a74..7cd071388c 100644 --- a/include/base_screen.h +++ b/include/base_screen.h @@ -33,7 +33,6 @@ #include #include -#include #include @@ -46,7 +45,6 @@ class BASE_SCREEN : public EDA_ITEM private: bool m_FlagModified; ///< Indicates current drawing has been modified. bool m_FlagSave; ///< Indicates automatic file save. - int m_UndoRedoCountMax; ///< undo/Redo command Max depth /** * The cross hair position in logical (drawing) units. The cross hair is not the cursor @@ -78,12 +76,8 @@ public: bool m_Initialized; - // Undo/redo list of commands - UNDO_REDO_CONTAINER m_UndoList; ///< Objects list for the undo command (old data) - UNDO_REDO_CONTAINER m_RedoList; ///< Objects list for the redo command (old data) - - int m_ScreenNumber; - int m_NumberOfScreens; + int m_ScreenNumber; + int m_NumberOfScreens; public: BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType = SCREEN_T ); @@ -102,83 +96,6 @@ public: void InitDataPoints( const wxSize& aPageSizeInternalUnits ); - /* general Undo/Redo command control */ - - /** - * Function ClearUndoORRedoList (virtual). - * this function must remove the aItemCount old commands from aList - * and delete commands, pickers and picked items if needed - * Because picked items must be deleted only if they are not in use, this - * is a virtual pure function that must be created for SCH_SCREEN and - * PCB_SCREEN - * @param aList = the UNDO_REDO_CONTAINER of commands - * @param aItemCount = number of old commands to delete. -1 to remove all - * old commands this will empty the list of commands. - * Commands are deleted from the older to the last. - */ - virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) - { } - - /** - * Function ClearUndoRedoList - * clear undo and redo list, using ClearUndoORRedoList() - * picked items are deleted by ClearUndoORRedoList() according to their - * status - */ - virtual void ClearUndoRedoList(); - - /** - * Function PushCommandToUndoList - * add a command to undo in undo list - * delete the very old commands when the max count of undo commands is - * reached - * ( using ClearUndoORRedoList) - */ - virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ); - - /** - * Function PushCommandToRedoList - * add a command to redo in redo list - * delete the very old commands when the max count of redo commands is - * reached - * ( using ClearUndoORRedoList) - */ - virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ); - - /** PopCommandFromUndoList - * return the last command to undo and remove it from list - * nothing is deleted. - */ - virtual PICKED_ITEMS_LIST* PopCommandFromUndoList(); - - /** PopCommandFromRedoList - * return the last command to undo and remove it from list - * nothing is deleted. - */ - virtual PICKED_ITEMS_LIST* PopCommandFromRedoList(); - - int GetUndoCommandCount() const - { - return m_UndoList.m_CommandsList.size(); - } - - int GetRedoCommandCount() const - { - return m_RedoList.m_CommandsList.size(); - } - - int GetMaxUndoItems() const { return m_UndoRedoCountMax; } - - void SetMaxUndoItems( int aMax ) - { - if( aMax >= 0 && aMax < ABS_MAX_UNDO_ITEMS ) - m_UndoRedoCountMax = aMax; - else - { - wxFAIL_MSG( "Maximum undo items not within limits" ); - m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS; - } - } void SetModify() { m_FlagModified = true; } void ClrModify() { m_FlagModified = false; } diff --git a/include/eda_base_frame.h b/include/eda_base_frame.h index 558ed86f87..b7393d9822 100644 --- a/include/eda_base_frame.h +++ b/include/eda_base_frame.h @@ -48,6 +48,7 @@ #include #include #include +#include // Option for main frames #define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS @@ -85,6 +86,9 @@ enum id_librarytype { LIBRARY_TYPE_SYMBOL }; +#define DEFAULT_MAX_UNDO_ITEMS 0 +#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2) + wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent ); @@ -137,13 +141,23 @@ protected: SETTINGS_MANAGER* m_settingsManager; - FILE_HISTORY* m_fileHistory; // The frame's recently opened file list + FILE_HISTORY* m_fileHistory; // The frame's recently opened file list bool m_hasAutoSave; bool m_autoSaveState; int m_autoSaveInterval; // The auto save interval time in seconds. wxTimer* m_autoSaveTimer; + bool m_FlagModified; // Indicates current drawing has been modified. + bool m_FlagSave; // Indicates automatic file save. + int m_UndoRedoCountMax; // undo/Redo command Max depth + +public: + // Undo/redo list of commands + UNDO_REDO_CONTAINER m_UndoList; // Objects list for the undo command (old data) + UNDO_REDO_CONTAINER m_RedoList; // Objects list for the redo command (old data) + +protected: wxString m_mruPath; // Most recently used path. EDA_UNITS m_userUnits; @@ -521,6 +535,85 @@ public: * @return the undecorated window size */ wxSize GetWindowSize(); + + + /* general Undo/Redo command control */ + + /** + * Function ClearUndoORRedoList (virtual). + * this function must remove the aItemCount old commands from aList + * and delete commands, pickers and picked items if needed + * Because picked items must be deleted only if they are not in use, this + * is a virtual pure function that must be created for SCH_SCREEN and + * PCB_SCREEN + * @param aList = the UNDO_REDO_CONTAINER of commands + * @param aItemCount = number of old commands to delete. -1 to remove all + * old commands this will empty the list of commands. + * Commands are deleted from the older to the last. + */ + virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) + { } + + /** + * Function ClearUndoRedoList + * clear undo and redo list, using ClearUndoORRedoList() + * picked items are deleted by ClearUndoORRedoList() according to their + * status + */ + virtual void ClearUndoRedoList(); + + /** + * Function PushCommandToUndoList + * add a command to undo in undo list + * delete the very old commands when the max count of undo commands is + * reached + * ( using ClearUndoORRedoList) + */ + virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ); + + /** + * Function PushCommandToRedoList + * add a command to redo in redo list + * delete the very old commands when the max count of redo commands is + * reached + * ( using ClearUndoORRedoList) + */ + virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ); + + /** PopCommandFromUndoList + * return the last command to undo and remove it from list + * nothing is deleted. + */ + virtual PICKED_ITEMS_LIST* PopCommandFromUndoList(); + + /** PopCommandFromRedoList + * return the last command to undo and remove it from list + * nothing is deleted. + */ + virtual PICKED_ITEMS_LIST* PopCommandFromRedoList(); + + int GetUndoCommandCount() const + { + return m_UndoList.m_CommandsList.size(); + } + + int GetRedoCommandCount() const + { + return m_RedoList.m_CommandsList.size(); + } + + int GetMaxUndoItems() const { return m_UndoRedoCountMax; } + + void SetMaxUndoItems( int aMax ) + { + if( aMax >= 0 && aMax < ABS_MAX_UNDO_ITEMS ) + m_UndoRedoCountMax = aMax; + else + { + wxFAIL_MSG( "Maximum undo items not within limits" ); + m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS; + } + } }; diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h index ea5139d353..eabc8ea9b5 100644 --- a/include/eda_draw_frame.h +++ b/include/eda_draw_frame.h @@ -50,8 +50,6 @@ namespace KIGFX using KIGFX::COLOR4D; using KIGFX::RENDER_SETTINGS; -#define DEFAULT_MAX_UNDO_ITEMS 0 -#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2) #define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" ) #define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" ) #define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" ) diff --git a/include/pcb_screen.h b/include/pcb_screen.h index da03e499ac..211eaa7e4e 100644 --- a/include/pcb_screen.h +++ b/include/pcb_screen.h @@ -22,10 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/** - * @file pcb_screen.h - */ - #ifndef PCB_SCREEN_H #define PCB_SCREEN_H @@ -34,9 +30,6 @@ #include -class UNDO_REDO_CONTAINER; - - /* Handle info to display a board */ class PCB_SCREEN : public BASE_SCREEN { @@ -46,35 +39,11 @@ public: PCB_LAYER_ID m_Route_Layer_BOTTOM; public: - /** * Constructor * @param aPageSizeIU is the size of the initial paper page in internal units. */ PCB_SCREEN( const wxSize& aPageSizeIU ); - - ~PCB_SCREEN(); - - - /* full undo redo management : */ - - // use BASE_SCREEN::ClearUndoRedoList() - // use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ) - // use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ) - - /** - * Function ClearUndoORRedoList - * free the undo or redo list from List element - * Wrappers are deleted. - * datas pointed by wrappers are deleted if not in use in schematic - * i.e. when they are copy of a schematic item or they are no more in use - * (DELETED) - * @param aList = the UNDO_REDO_CONTAINER to clear - * @param aItemCount = the count of items to remove. < 0 for all items - * items are removed from the beginning of the list. - * So this function can be called to remove old commands - */ - void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; }; #endif // PCB_SCREEN_H diff --git a/include/undo_redo_container.h b/include/undo_redo_container.h index 0d3d7bb38d..30535ab6df 100644 --- a/include/undo_redo_container.h +++ b/include/undo_redo_container.h @@ -31,6 +31,7 @@ class PICKED_ITEMS_LIST; +class BASE_SCREEN; /** @@ -90,8 +91,13 @@ private: * copy of an active item) and m_Link points the active * item in schematic */ + BASE_SCREEN* m_screen; /* For new and deleted items the screen the item should + * be added to/removed from. */ + public: - ITEM_PICKER( EDA_ITEM* aItem = NULL, UNDO_REDO_T aUndoRedoStatus = UR_UNSPECIFIED ); +// ITEM_PICKER( EDA_ITEM* aItem = NULL, UNDO_REDO_T aStatus = UR_UNSPECIFIED ); + ITEM_PICKER(); + ITEM_PICKER( BASE_SCREEN* aScreen, EDA_ITEM* aItem, UNDO_REDO_T aStatus = UR_UNSPECIFIED ); EDA_ITEM* GetItem() const { return m_pickedItem; } @@ -114,6 +120,8 @@ public: void SetLink( EDA_ITEM* aItem ) { m_link = aItem; } EDA_ITEM* GetLink() const { return m_link; } + + BASE_SCREEN* GetScreen() const { return m_screen; } }; @@ -125,10 +133,10 @@ public: class PICKED_ITEMS_LIST { public: - UNDO_REDO_T m_Status; /* info about operation to undo/redo for this item. can be - * UR_UNSPECIFIED */ - wxPoint m_TransformPoint; /* used to undo redo command by the same command: usually - * need to know the rotate point or the move vector */ + UNDO_REDO_T m_Status; /* info about operation to undo/redo for this item. can be + * UR_UNSPECIFIED */ + wxPoint m_TransformPoint; /* used to undo redo command by the same command: usually + * need to know the rotate point or the move vector */ private: std::vector m_ItemsList; @@ -211,6 +219,13 @@ public: */ EDA_ITEM* GetPickedItem( unsigned int aIdx ) const; + /** + * Function GetScreenForItem + * @return A pointer to the picked item's sceen + * @param aIdx Index of the picked item in the picked list + */ + BASE_SCREEN* GetScreenForItem( unsigned int aIdx ) const; + /** * Function GetPickedItemLink * @return link of the picked item, or null if does not exist diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index 43bca0376f..4757d80ee7 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -22,7 +22,6 @@ set( PL_EDITOR_SRCS dialogs/panel_pl_editor_color_settings.cpp dialogs/panel_pl_editor_color_settings_base.cpp design_inspector.cpp - pl_editor_screen.cpp pl_editor_layout.cpp files.cpp pl_editor_frame.cpp diff --git a/pagelayout_editor/dialogs/dialogs_for_printing.cpp b/pagelayout_editor/dialogs/dialogs_for_printing.cpp index 2057e1b079..cb568f7ef2 100644 --- a/pagelayout_editor/dialogs/dialogs_for_printing.cpp +++ b/pagelayout_editor/dialogs/dialogs_for_printing.cpp @@ -152,7 +152,7 @@ void PLEDITOR_PRINTOUT::PrintPage( int aPageNum ) wxPoint old_org; wxRect fitRect; wxDC* dc = GetDC(); - PL_EDITOR_SCREEN* screen = m_parent->GetScreen(); + BASE_SCREEN* screen = m_parent->GetScreen(); // Save current offsets and clip box. tmp_startvisu = screen->m_StartVisu; diff --git a/pagelayout_editor/menubar.cpp b/pagelayout_editor/menubar.cpp index 0eb462af8f..fc0302ba60 100644 --- a/pagelayout_editor/menubar.cpp +++ b/pagelayout_editor/menubar.cpp @@ -90,10 +90,10 @@ void PL_EDITOR_FRAME::ReCreateMenuBar() CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetUndoCommandCount() != 0; + return GetUndoCommandCount() != 0; }; auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetRedoCommandCount() != 0; + return GetRedoCommandCount() != 0; }; auto idleCondition = [] ( const SELECTION& sel ) { return !sel.Front() || sel.Front()->GetEditFlags() == 0; diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 166ba1391c..2f7d23f6e9 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -114,7 +113,7 @@ PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : LoadSettings( config() ); wxSize pageSizeIU = GetPageLayout().GetPageSettings().GetSizeIU(); - SetScreen( new PL_EDITOR_SCREEN( pageSizeIU ) ); + SetScreen( new BASE_SCREEN( pageSizeIU ) ); setupTools(); ReCreateMenuBar(); @@ -612,11 +611,6 @@ void PL_EDITOR_FRAME::DisplayGridMsg() void PL_EDITOR_FRAME::UpdateStatusBar() { - PL_EDITOR_SCREEN* screen = (PL_EDITOR_SCREEN*) GetScreen(); - - if( !screen ) - return; - // Display Zoom level: EDA_DRAW_FRAME::UpdateStatusBar(); @@ -663,16 +657,10 @@ void PL_EDITOR_FRAME::UpdateStatusBar() switch( GetUserUnits() ) { - case EDA_UNITS::INCHES: - SetStatusText( _( "inches" ), 6 ); - break; - case EDA_UNITS::MILLIMETRES: - SetStatusText( _( "mm" ), 6 ); - break; - case EDA_UNITS::UNSCALED: - SetStatusText( wxEmptyString, 6 ); - break; - default: wxASSERT( false ); break; + case EDA_UNITS::INCHES: SetStatusText( _( "inches" ), 6 ); break; + case EDA_UNITS::MILLIMETRES: SetStatusText( _( "mm" ), 6 ); break; + case EDA_UNITS::UNSCALED: SetStatusText( wxEmptyString, 6 ); break; + default: wxASSERT( false ); break; } wxString line; @@ -689,12 +677,15 @@ void PL_EDITOR_FRAME::UpdateStatusBar() SetStatusText( line, 2 ); // Display relative coordinates: - double dx = cursorPos.x - screen->m_LocalOrigin.x; - double dy = cursorPos.y - screen->m_LocalOrigin.y; - dXpos = To_User_Unit( GetUserUnits(), dx * Xsign ); - dYpos = To_User_Unit( GetUserUnits(), dy * Ysign ); - line.Printf( locformatter, dXpos, dYpos ); - SetStatusText( line, 3 ); + if( GetScreen() ) + { + double dx = cursorPos.x - GetScreen()->m_LocalOrigin.x; + double dy = cursorPos.y - GetScreen()->m_LocalOrigin.y; + dXpos = To_User_Unit( GetUserUnits(), dx * Xsign ); + dYpos = To_User_Unit( GetUserUnits(), dy * Ysign ); + line.Printf( locformatter, dXpos, dYpos ); + SetStatusText( line, 3 ); + } DisplayGridMsg(); @@ -819,7 +810,7 @@ WS_DATA_ITEM* PL_EDITOR_FRAME::AddPageLayoutItem( int aType ) void PL_EDITOR_FRAME::OnNewPageLayout() { - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); GetScreen()->ClrModify(); GetCanvas()->DisplayWorksheet(); @@ -842,3 +833,25 @@ void PL_EDITOR_FRAME::OnNewPageLayout() } +void PL_EDITOR_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) +{ + if( aItemCount == 0 ) + return; + + unsigned icnt = aList.m_CommandsList.size(); + + if( aItemCount > 0 ) + icnt = aItemCount; + + for( unsigned ii = 0; ii < icnt; ii++ ) + { + if( aList.m_CommandsList.size() == 0 ) + break; + + PICKED_ITEMS_LIST* curr_cmd = aList.m_CommandsList[0]; + aList.m_CommandsList.erase( aList.m_CommandsList.begin() ); + + curr_cmd->ClearListAndDeleteItems(); + delete curr_cmd; // Delete command + } +} diff --git a/pagelayout_editor/pl_editor_frame.h b/pagelayout_editor/pl_editor_frame.h index 5cd3c84137..6678f34be0 100644 --- a/pagelayout_editor/pl_editor_frame.h +++ b/pagelayout_editor/pl_editor_frame.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -124,11 +124,6 @@ public: PL_DRAW_PANEL_GAL* GetCanvas() const override; - PL_EDITOR_SCREEN* GetScreen() const override - { - return (PL_EDITOR_SCREEN*) EDA_DRAW_FRAME::GetScreen(); - } - const wxPoint& GetGridOrigin() const override { return m_grid_origin; } void SetGridOrigin( const wxPoint& aPoint ) override { m_grid_origin = aPoint; } @@ -266,9 +261,8 @@ public: /** * Save a copy of the description (in a S expr string) for Undo/redo commands. - * Optionally save the pageInfo and titleBlock as well. */ - void SaveCopyInUndoList( bool aSavePageSettingsAndTitleBlock = false ); + void SaveCopyInUndoList(); /** Redo the last edit: * - Place the current edited layout in undo list @@ -288,6 +282,11 @@ public: */ void RollbackFromUndo(); + /** + * Function ClearUndoORRedoList + */ + void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; + protected: bool saveCurrentPageLayout(); diff --git a/pagelayout_editor/pl_editor_screen.cpp b/pagelayout_editor/pl_editor_screen.cpp deleted file mode 100644 index 1076e1b45f..0000000000 --- a/pagelayout_editor/pl_editor_screen.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. - * @author Jean-Pierre Charras, jp.charras at wanadoo.fr - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include - - -PL_EDITOR_SCREEN::PL_EDITOR_SCREEN( const wxSize& aPageSizeIU ) : - BASE_SCREEN( aPageSizeIU ) -{ - // pl_editor uses the same frame position as schematic and board editors - m_Center = false; - - m_NumberOfScreens = 2; -} - - -PL_EDITOR_SCREEN::~PL_EDITOR_SCREEN() -{ - ClearUndoRedoList(); -} - - -void PL_EDITOR_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) -{ - if( aItemCount == 0 ) - return; - - unsigned icnt = aList.m_CommandsList.size(); - - if( aItemCount > 0 ) - icnt = aItemCount; - - for( unsigned ii = 0; ii < icnt; ii++ ) - { - if( aList.m_CommandsList.size() == 0 ) - break; - - PICKED_ITEMS_LIST* curr_cmd = aList.m_CommandsList[0]; - aList.m_CommandsList.erase( aList.m_CommandsList.begin() ); - - curr_cmd->ClearListAndDeleteItems(); - delete curr_cmd; // Delete command - } -} diff --git a/pagelayout_editor/pl_editor_screen.h b/pagelayout_editor/pl_editor_screen.h deleted file mode 100644 index 487fcf0808..0000000000 --- a/pagelayout_editor/pl_editor_screen.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Jean-Pierre Charras, jp.charras at wanadoo.fr - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef CLASS_PL_EDITOR_SCREEN_H_ -#define CLASS_PL_EDITOR_SCREEN_H_ - - -#include - -class WS_DATA_ITEM; - - -class PL_EDITOR_SCREEN : public BASE_SCREEN -{ -public: - /** - * Constructor - * @param aPageSizeIU is the size of the initial paper page in internal units. - */ - PL_EDITOR_SCREEN( const wxSize& aPageSizeIU ); - - ~PL_EDITOR_SCREEN(); - - /** - * Function ClearUndoORRedoList - * virtual pure in BASE_SCREEN, so it must be defined here - */ - void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; -}; - - -#endif // CLASS_PL_EDITOR_SCREEN_H_ diff --git a/pagelayout_editor/pl_editor_undo_redo.cpp b/pagelayout_editor/pl_editor_undo_redo.cpp index 70c719a3d8..b75e136f13 100644 --- a/pagelayout_editor/pl_editor_undo_redo.cpp +++ b/pagelayout_editor/pl_editor_undo_redo.cpp @@ -24,27 +24,25 @@ */ #include -#include #include -#include - #include #include #include #include #include -void PL_EDITOR_FRAME::SaveCopyInUndoList( bool aSavePageSettingsAndTitleBlock ) + +void PL_EDITOR_FRAME::SaveCopyInUndoList() { PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); WS_PROXY_UNDO_ITEM* copyItem = new WS_PROXY_UNDO_ITEM( this ); - ITEM_PICKER wrapper( copyItem, UR_LIBEDIT ); + ITEM_PICKER wrapper( GetScreen(), copyItem, UR_LIBEDIT ); lastcmd->PushItem( wrapper ); - GetScreen()->PushCommandToUndoList( lastcmd ); + PushCommandToUndoList( lastcmd ); // Clear redo list, because after new save there is no redo to do. - GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); + ClearUndoORRedoList( m_RedoList ); } @@ -56,17 +54,19 @@ void PL_EDITOR_FRAME::GetLayoutFromRedoList() { PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); - if ( GetScreen()->GetRedoCommandCount() <= 0 ) + if ( GetRedoCommandCount() <= 0 ) return; - ITEM_PICKER redoWrapper = GetScreen()->PopCommandFromRedoList()->PopItem(); + ITEM_PICKER redoWrapper = PopCommandFromRedoList()->PopItem(); WS_PROXY_UNDO_ITEM* redoItem = static_cast( redoWrapper.GetItem() ); bool pageSettingsAndTitleBlock = redoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; PICKED_ITEMS_LIST* undoCmd = new PICKED_ITEMS_LIST(); + WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ); + ITEM_PICKER undoWrapper( GetScreen(), undoItem ); - undoCmd->PushItem( new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ) ); - GetScreen()->PushCommandToUndoList( undoCmd ); + undoCmd->PushItem( undoWrapper ); + PushCommandToUndoList( undoCmd ); selTool->ClearSelection(); redoItem->Restore( this, GetCanvas()->GetView() ); @@ -91,17 +91,19 @@ void PL_EDITOR_FRAME::GetLayoutFromUndoList() { PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); - if ( GetScreen()->GetUndoCommandCount() <= 0 ) + if ( GetUndoCommandCount() <= 0 ) return; - ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem(); + ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem(); WS_PROXY_UNDO_ITEM* undoItem = static_cast( undoWrapper.GetItem() ); bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; PICKED_ITEMS_LIST* redoCmd = new PICKED_ITEMS_LIST(); + WS_PROXY_UNDO_ITEM* redoItem = new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ); + ITEM_PICKER redoWrapper( GetScreen(), redoItem ); - redoCmd->PushItem( new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ) ); - GetScreen()->PushCommandToRedoList( redoCmd ); + redoCmd->PushItem( redoWrapper ); + PushCommandToRedoList( redoCmd ); selTool->ClearSelection(); undoItem->Restore( this, GetCanvas()->GetView() ); @@ -125,10 +127,10 @@ void PL_EDITOR_FRAME::RollbackFromUndo() { PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); - if ( GetScreen()->GetUndoCommandCount() <= 0 ) + if ( GetUndoCommandCount() <= 0 ) return; - ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem(); + ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem(); WS_PROXY_UNDO_ITEM* undoItem = static_cast( undoWrapper.GetItem() ); bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; diff --git a/pagelayout_editor/toolbars_pl_editor.cpp b/pagelayout_editor/toolbars_pl_editor.cpp index e1a199b221..e55500be03 100644 --- a/pagelayout_editor/toolbars_pl_editor.cpp +++ b/pagelayout_editor/toolbars_pl_editor.cpp @@ -151,8 +151,8 @@ void PL_EDITOR_FRAME::SyncToolbars() #define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) ) m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); - m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); m_mainToolBar->Refresh(); diff --git a/pagelayout_editor/tools/pl_editor_control.cpp b/pagelayout_editor/tools/pl_editor_control.cpp index ddda4e5310..c5bad74879 100644 --- a/pagelayout_editor/tools/pl_editor_control.cpp +++ b/pagelayout_editor/tools/pl_editor_control.cpp @@ -85,7 +85,7 @@ int PL_EDITOR_CONTROL::SaveAs( const TOOL_EVENT& aEvent ) int PL_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent ) { - m_frame->SaveCopyInUndoList( true ); + m_frame->SaveCopyInUndoList(); DIALOG_PAGES_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) ); dlg.SetWksFileName( m_frame->GetCurrentFileName() ); diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index b83583a6e8..a7c9d8986d 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -123,7 +123,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a if( aCreateUndoEntry ) { - ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED ); + ITEM_PICKER itemWrapper( nullptr, ent.m_item, UR_CHANGED ); itemWrapper.SetLink( ent.m_copy ); undoList.PushItem( itemWrapper ); frame->SaveCopyInUndoList( undoList, UR_CHANGED ); @@ -158,7 +158,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a else { if( aCreateUndoEntry ) - undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) ); + undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UR_NEW ) ); if( !( changeFlags & CHT_DONE ) ) board->Add( boardItem ); // handles connectivity @@ -171,7 +171,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a case CHT_REMOVE: { if( !m_editModules && aCreateUndoEntry ) - undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) ); + undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UR_DELETED ) ); if( boardItem->IsSelected() ) { @@ -252,7 +252,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a { if( !m_editModules && aCreateUndoEntry ) { - ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); + ITEM_PICKER itemWrapper( nullptr, boardItem, UR_CHANGED ); wxASSERT( ent.m_copy ); itemWrapper.SetLink( ent.m_copy ); undoList.PushItem( itemWrapper ); @@ -299,7 +299,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a if( aCreateUndoEntry ) { - ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); + ITEM_PICKER itemWrapper( nullptr, boardItem, UR_CHANGED ); wxASSERT( ent.m_copy ); itemWrapper.SetLink( ent.m_copy ); undoList.PushItem( itemWrapper ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 5342a9efcb..4c0f83080e 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1703,7 +1703,7 @@ ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, if( aNewZonesList ) { - ITEM_PICKER picker( new_area, UR_NEW ); + ITEM_PICKER picker( nullptr, new_area, UR_NEW ); aNewZonesList->PushItem( picker ); } @@ -1718,7 +1718,7 @@ void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to if( aDeletedList ) { - ITEM_PICKER picker( area_to_remove, UR_DELETED ); + ITEM_PICKER picker( nullptr, area_to_remove, UR_DELETED ); aDeletedList->PushItem( picker ); Remove( area_to_remove ); // remove from zone list, but does not delete it } diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp index bfb0e5e2e8..e146763bcc 100644 --- a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp +++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp @@ -305,7 +305,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::processItem( PICKED_ITEMS_LIST* aUndoLi { if( aUndoList->FindItem( aItem ) < 0 ) { - ITEM_PICKER picker( aItem, UR_CHANGED ); + ITEM_PICKER picker( nullptr, aItem, UR_CHANGED ); picker.SetLink( aItem->Clone() ); aUndoList->PushItem( picker ); } diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index b868d4bc36..f3dc5430bc 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -104,7 +104,7 @@ int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, if( aItemsListPicker ) { aTrackItem->SetWidth( initial_width ); - ITEM_PICKER picker( aTrackItem, UR_CHANGED ); + ITEM_PICKER picker( nullptr, aTrackItem, UR_CHANGED ); picker.SetLink( aTrackItem->Clone() ); aItemsListPicker->PushItem( picker ); aTrackItem->SetWidth( new_width ); diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 81c301574c..6afb365e19 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -174,7 +174,6 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, // In modedit, set the default paper size to A4 for plot/print SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) ); SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); - GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); // Create the manager and dispatcher & route draw panel events to the dispatcher setupTools(); diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index f8261e21f5..69e267f84c 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -985,7 +985,7 @@ bool FOOTPRINT_EDIT_FRAME::RevertFootprint() Update3DView( true ); - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); GetScreen()->ClrModify(); updateView(); diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 91043b83bb..a85e9a94e2 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -55,7 +55,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal ) ReleaseFile(); // Clear undo and redo lists because we want a full deletion - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); GetScreen()->ClrModify(); if( !aFinal ) @@ -109,7 +109,7 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery ) } // Clear undo and redo lists because we want a full deletion - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); GetScreen()->ClrModify(); BOARD* board = new BOARD; diff --git a/pcbnew/load_select_footprint.cpp b/pcbnew/load_select_footprint.cpp index fbecf7c156..b621a95091 100644 --- a/pcbnew/load_select_footprint.cpp +++ b/pcbnew/load_select_footprint.cpp @@ -139,7 +139,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) m_adapter->SetPreselectNode( newModule->GetFPID(), 0 ); - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); GetScreen()->ClrModify(); // Update the save items if needed. @@ -482,7 +482,7 @@ void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, bool aRecreateRatsnest ) } else if( aModule->IsMoving() ) { - ITEM_PICKER picker( aModule, UR_CHANGED ); + ITEM_PICKER picker( nullptr, aModule, UR_CHANGED ); picker.SetLink( s_ModuleInitialCopy ); s_PickedList.PushItem( picker ); s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy. diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp index cfaace4e0f..5f61b96fb3 100644 --- a/pcbnew/menubar_footprint_editor.cpp +++ b/pcbnew/menubar_footprint_editor.cpp @@ -111,10 +111,10 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; + return GetUndoCommandCount() > 0; }; auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; + return GetRedoCommandCount() > 0; }; auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { return ToolStackIsEmpty(); diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index c6ffc13f17..e493c52ba4 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -210,10 +210,10 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; + return GetUndoCommandCount() > 0; }; auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; + return GetRedoCommandCount() > 0; }; auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { return ToolStackIsEmpty(); diff --git a/pcbnew/pcb_base_edit_frame.cpp b/pcbnew/pcb_base_edit_frame.cpp index 84ccf5f054..cd8a9621f2 100644 --- a/pcbnew/pcb_base_edit_frame.cpp +++ b/pcbnew/pcb_base_edit_frame.cpp @@ -24,13 +24,10 @@ #include #include -#include #include #include #include -#include #include -#include #include "footprint_info_impl.h" #include #include @@ -139,3 +136,5 @@ COLOR_SETTINGS* PCB_BASE_EDIT_FRAME::GetColorSettings() { return Pgm().GetSettingsManager().GetColorSettings( GetPcbNewSettings()->m_ColorTheme ); } + + diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index 7d69f7f456..3d44d1ed54 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -185,6 +185,26 @@ public: COLOR_SETTINGS* GetColorSettings() override; + /* full undo redo management : */ + + // use EDA_BASE_FRAME::ClearUndoRedoList() + // use EDA_BASE_FRAME::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem ) + // use EDA_BASE_FRAME::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem ) + + /** + * Function ClearUndoORRedoList + * free the undo or redo list from List element + * Wrappers are deleted. + * datas pointed by wrappers are deleted if not in use in schematic + * i.e. when they are copy of a schematic item or they are no more in use + * (DELETED) + * @param aList = the UNDO_REDO_CONTAINER to clear + * @param aItemCount = the count of items to remove. < 0 for all items + * items are removed from the beginning of the list. + * So this function can be called to remove old commands + */ + void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override; + protected: /// User defined rotation angle (in tenths of a degree). int m_rotationAngle; diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index dbd79947aa..85e4206d2b 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -206,7 +206,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : LoadSettings( config() ); SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); - GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); // PCB drawings start in the upper left corner. GetScreen()->m_Center = false; diff --git a/pcbnew/pcb_screen.cpp b/pcbnew/pcb_screen.cpp index 71000cfd84..04b6fe0e4d 100644 --- a/pcbnew/pcb_screen.cpp +++ b/pcbnew/pcb_screen.cpp @@ -36,9 +36,3 @@ PCB_SCREEN::PCB_SCREEN( const wxSize& aPageSizeIU ) : m_Route_Layer_TOP = F_Cu; // default layers pair for vias (bottom to top) m_Route_Layer_BOTTOM = B_Cu; } - - -PCB_SCREEN::~PCB_SCREEN() -{ - ClearUndoRedoList(); -} diff --git a/pcbnew/specctra_import_export/specctra_import.cpp b/pcbnew/specctra_import_export/specctra_import.cpp index bbb4cb4b9f..c26dd093f5 100644 --- a/pcbnew/specctra_import_export/specctra_import.cpp +++ b/pcbnew/specctra_import_export/specctra_import.cpp @@ -56,7 +56,7 @@ bool PCB_EDIT_FRAME::ImportSpecctraSession( const wxString& fullFileName ) // To avoid issues with undo/redo lists (dangling pointers) // clear the lists // todo: use undo/redo feature - GetScreen()->ClearUndoRedoList(); + ClearUndoRedoList(); SPECCTRA_DB db; LOCALE_IO toggle; diff --git a/pcbnew/swig/pcbnew_action_plugins.cpp b/pcbnew/swig/pcbnew_action_plugins.cpp index 823217c5a1..896092004b 100644 --- a/pcbnew/swig/pcbnew_action_plugins.cpp +++ b/pcbnew/swig/pcbnew_action_plugins.cpp @@ -222,29 +222,28 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) // Append tracks: for( auto item : currentPcb->Tracks() ) { - ITEM_PICKER picker( item, UR_CHANGED ); + ITEM_PICKER picker( nullptr, item, UR_CHANGED ); itemsList.PushItem( picker ); } // Append modules: for( auto item : currentPcb->Modules() ) { - ITEM_PICKER picker( item, UR_CHANGED ); + ITEM_PICKER picker( nullptr, item, UR_CHANGED ); itemsList.PushItem( picker ); } // Append drawings for( auto item : currentPcb->Drawings() ) { - ITEM_PICKER picker( item, UR_CHANGED ); + ITEM_PICKER picker( nullptr, item, UR_CHANGED ); itemsList.PushItem( picker ); } // Append zones outlines for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) { - ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( - ii ), UR_CHANGED ); + ITEM_PICKER picker( nullptr, (EDA_ITEM*) currentPcb->GetArea( ii ), UR_CHANGED ); itemsList.PushItem( picker ); } @@ -270,7 +269,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) } else { - oldBuffer = GetScreen()->PopCommandFromUndoList(); + oldBuffer = PopCommandFromUndoList(); wxASSERT( oldBuffer ); } @@ -280,15 +279,15 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) // The list of existing items after running the action script std::set currItemList; // Append tracks: - for( auto item : currentPcb->Tracks() ) + for( TRACK* item : currentPcb->Tracks() ) currItemList.insert( item ); // Append modules: - for( auto item : currentPcb->Modules() ) + for( MODULE* item : currentPcb->Modules() ) currItemList.insert( item ); // Append drawings - for( auto item : currentPcb->Drawings() ) + for( BOARD_ITEM* item : currentPcb->Drawings() ) currItemList.insert( item ); // Append zones outlines @@ -299,7 +298,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) for( unsigned int i = 0; i < oldBuffer->GetCount(); i++ ) { BOARD_ITEM* item = (BOARD_ITEM*) oldBuffer->GetPickedItem( i ); - ITEM_PICKER picker( item, UR_DELETED ); + ITEM_PICKER picker( nullptr, item, UR_DELETED ); wxASSERT( item ); @@ -314,29 +313,29 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) } // Find new modules - for( auto item : currentPcb->Modules() ) + for( MODULE* item : currentPcb->Modules() ) { if( !oldBuffer->ContainsItem( item ) ) { - ITEM_PICKER picker( item, UR_NEW ); + ITEM_PICKER picker( nullptr, item, UR_NEW ); oldBuffer->PushItem( picker ); } } - for( auto item : currentPcb->Tracks() ) + for( TRACK* item : currentPcb->Tracks() ) { if( !oldBuffer->ContainsItem( item ) ) { - ITEM_PICKER picker( item, UR_NEW ); + ITEM_PICKER picker( nullptr, item, UR_NEW ); oldBuffer->PushItem( picker ); } } - for( auto item : currentPcb->Drawings() ) + for( BOARD_ITEM* item : currentPcb->Drawings() ) { if( !oldBuffer->ContainsItem( item ) ) { - ITEM_PICKER picker( item, UR_NEW ); + ITEM_PICKER picker( nullptr, item, UR_NEW ); oldBuffer->PushItem( picker ); } } @@ -345,8 +344,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) { if( !oldBuffer->ContainsItem( (EDA_ITEM*) currentPcb->GetArea( ii ) ) ) { - ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( - ii ), UR_NEW ); + ITEM_PICKER picker( nullptr, (EDA_ITEM*) currentPcb->GetArea( ii ), UR_NEW ); oldBuffer->PushItem( picker ); } } @@ -354,7 +352,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin ) if( oldBuffer->GetCount() ) { OnModify(); - GetScreen()->PushCommandToUndoList( oldBuffer ); + PushCommandToUndoList( oldBuffer ); } else { diff --git a/pcbnew/toolbars_footprint_editor.cpp b/pcbnew/toolbars_footprint_editor.cpp index dc7cebe31a..ead227f1cd 100644 --- a/pcbnew/toolbars_footprint_editor.cpp +++ b/pcbnew/toolbars_footprint_editor.cpp @@ -231,8 +231,8 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars() else m_mainToolBar->Toggle( PCB_ACTIONS::saveToLibrary, IsContentModified() ); - m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); m_mainToolBar->Toggle( PCB_ACTIONS::footprintProperties, GetBoard()->GetFirstModule() ); m_mainToolBar->Refresh(); diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index e1cb9e82b7..ddc5869982 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -707,8 +707,8 @@ void PCB_EDIT_FRAME::SyncToolbars() int zoneMode = opts.m_DisplayZonesMode; m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); - m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); #if defined(KICAD_SCRIPTING_WXPYTHON) if( IsWxPythonLoaded() ) diff --git a/pcbnew/tools/footprint_editor_tools.cpp b/pcbnew/tools/footprint_editor_tools.cpp index 450a12df9d..64c3c4d73a 100644 --- a/pcbnew/tools/footprint_editor_tools.cpp +++ b/pcbnew/tools/footprint_editor_tools.cpp @@ -220,10 +220,7 @@ int FOOTPRINT_EDITOR_TOOLS::ImportFootprint( const TOOL_EVENT& aEvent ) if( m_frame->GetBoard()->GetFirstModule() ) m_frame->GetBoard()->GetFirstModule()->ClearFlags(); - // Clear undo and redo lists because we don't have handling to in - // FP editor to undo across imports (the module _is_ the board with the stack) - // todo: Abstract undo/redo stack to a higher element or keep consistent board item in fpeditor - frame()->GetScreen()->ClearUndoRedoList(); + frame()->ClearUndoRedoList(); m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true ); m_frame->OnModify(); diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index d4c16c0017..7a853c6b05 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -290,7 +290,7 @@ int PCB_EDITOR_CONTROL::PageSettings( const TOOL_EVENT& aEvent ) { PICKED_ITEMS_LIST undoCmd; WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( m_frame ); - ITEM_PICKER wrapper( undoItem, UR_PAGESETTINGS ); + ITEM_PICKER wrapper( nullptr, undoItem, UR_PAGESETTINGS ); undoCmd.PushItem( wrapper ); m_frame->SaveCopyInUndoList( undoCmd, UR_PAGESETTINGS ); diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index 320481ebbe..8355c00a48 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -183,7 +183,7 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCo const wxPoint& aTransformPoint ) { PICKED_ITEMS_LIST commandToUndo; - commandToUndo.PushItem( ITEM_PICKER( aItem, aCommandType ) ); + commandToUndo.PushItem( ITEM_PICKER( nullptr, aItem, aCommandType ) ); SaveCopyInUndoList( commandToUndo, aCommandType, aTransformPoint ); } @@ -246,7 +246,7 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis clone->Reference().ClearEditFlags(); clone->Value().ClearEditFlags(); - ITEM_PICKER picker( item, UR_CHANGED ); + ITEM_PICKER picker( nullptr, item, UR_CHANGED ); picker.SetLink( clone ); commandToUndo->PushItem( picker ); @@ -315,10 +315,10 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ - GetScreen()->PushCommandToUndoList( commandToUndo ); + PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after a new command one cannot redo a command */ - GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); + ClearUndoORRedoList( m_RedoList ); } else { @@ -334,21 +334,21 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent ) if( UndoRedoBlocked() ) return; - if( GetScreen()->GetUndoCommandCount() <= 0 ) + if( GetUndoCommandCount() <= 0 ) return; // Inform tools that undo command was issued m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); // Get the old list - PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* List = PopCommandFromUndoList(); // Undo the command PutDataInPreviousState( List, false ); // Put the old list in RedoList List->ReversePickersListOrder(); - GetScreen()->PushCommandToRedoList( List ); + PushCommandToRedoList( List ); OnModify(); @@ -363,21 +363,21 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) if( UndoRedoBlocked() ) return; - if( GetScreen()->GetRedoCommandCount() == 0 ) + if( GetRedoCommandCount() == 0 ) return; // Inform tools that redo command was issued m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); // Get the old list - PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); + PICKED_ITEMS_LIST* List = PopCommandFromRedoList(); // Redo the command PutDataInPreviousState( List, true ); // Put the old list in UndoList List->ReversePickersListOrder(); - GetScreen()->PushCommandToUndoList( List ); + PushCommandToUndoList( List ); OnModify(); @@ -585,7 +585,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool -void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) +void PCB_BASE_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) { if( aItemCount == 0 ) return; @@ -611,7 +611,7 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount void PCB_BASE_EDIT_FRAME::RollbackFromUndo() { - PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList(); + PICKED_ITEMS_LIST* undo = PopCommandFromUndoList(); PutDataInPreviousState( undo, false ); undo->ClearListAndDeleteItems(); diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index e5af37e772..b1c170e826 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -163,7 +163,7 @@ int SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb, int aNetCode, LA ZONE_CONTAINER* zoneDup = new ZONE_CONTAINER( *zone ); zoneDup->SetParent( aPcb ); - ITEM_PICKER picker( zone, UR_CHANGED ); + ITEM_PICKER picker( nullptr, zone, UR_CHANGED ); picker.SetLink( zoneDup ); aPickList.PushItem( picker ); copyCount++; diff --git a/qa/qa_utils/mocks.cpp b/qa/qa_utils/mocks.cpp index 0543570a1d..dc6775edbb 100644 --- a/qa/qa_utils/mocks.cpp +++ b/qa/qa_utils/mocks.cpp @@ -254,11 +254,6 @@ void DIALOG_FILTER_SELECTION::ExecuteCommand( wxCommandEvent& event ) } -void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount ) -{ -} - - void ROUTER_TOOL::NeighboringSegmentFilter( const VECTOR2I&, GENERAL_COLLECTOR& ) { }