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
This commit is contained in:
Jeff Young 2020-07-13 12:21:40 +01:00
parent 30eef410a9
commit 7340c97ef9
88 changed files with 768 additions and 881 deletions

View File

@ -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 ) : BASE_SCREEN::BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType ) :
EDA_ITEM( aParent, aType ) EDA_ITEM( aParent, aType )
{ {
m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
m_Initialized = false; m_Initialized = false;
m_ScreenNumber = 1; m_ScreenNumber = 1;
m_NumberOfScreens = 1; // Hierarchy: Root: 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) #if defined(DEBUG)
void BASE_SCREEN::Show( int nestLevel, std::ostream& os ) const void BASE_SCREEN::Show( int nestLevel, std::ostream& os ) const

View File

@ -81,6 +81,7 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
m_hasAutoSave( false ), m_hasAutoSave( false ),
m_autoSaveState( false ), m_autoSaveState( false ),
m_autoSaveInterval(-1 ), m_autoSaveInterval(-1 ),
m_UndoRedoCountMax( DEFAULT_MAX_UNDO_ITEMS ),
m_userUnits( EDA_UNITS::MILLIMETRES ) m_userUnits( EDA_UNITS::MILLIMETRES )
{ {
m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER ); m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
@ -156,10 +157,10 @@ EDA_BASE_FRAME::~EDA_BASE_FRAME()
delete m_autoSaveTimer; delete m_autoSaveTimer;
delete m_fileHistory; delete m_fileHistory;
ClearUndoRedoList();
if( SupportsShutdownBlockReason() ) if( SupportsShutdownBlockReason() )
{
RemoveShutdownBlockReason(); 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 ) void EDA_BASE_FRAME::ChangeUserUnits( EDA_UNITS aUnits )
{ {
SetUserUnits( aUnits ); SetUserUnits( aUnits );

View File

@ -570,9 +570,7 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
aCfg->m_System.units = static_cast<int>( m_userUnits ); aCfg->m_System.units = static_cast<int>( m_userUnits );
aCfg->m_System.first_run_shown = m_firstRunDialogSetting; aCfg->m_System.first_run_shown = m_firstRunDialogSetting;
aCfg->m_System.max_undo_items = GetMaxUndoItems();
if( GetScreen() )
aCfg->m_System.max_undo_items = GetScreen()->GetMaxUndoItems();
m_galDisplayOptions.WriteConfig( *window ); m_galDisplayOptions.WriteConfig( *window );

View File

@ -28,12 +28,34 @@
#include <undo_redo_container.h> #include <undo_redo_container.h>
/*
ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus ) ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus )
{ {
m_undoRedoStatus = aUndoRedoStatus; m_undoRedoStatus = aUndoRedoStatus;
SetItem( aItem ); SetItem( aItem );
m_pickerFlags = 0; 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_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 EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const
{ {
if( aIdx < m_ItemsList.size() ) if( aIdx < m_ItemsList.size() )

View File

@ -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() COLOR4D DISPLAY_FOOTPRINTS_FRAME::GetGridColor()
{ {
return COLOR4D( DARKGRAY ); return COLOR4D( DARKGRAY );

View File

@ -58,18 +58,34 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map<wxString, wxString>& 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<SCH_COMPONENT*>( 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 ) if( aCurrentSheetOnly )
{ {
SCH_SCREEN* screen = GetScreen(); clearAnnotation( GetScreen(), &GetCurrentSheet() );
wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
screen->ClearAnnotation( &GetCurrentSheet() );
} }
else else
{ {
SCH_SCREENS ScreenList( Schematic().Root() ); for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() )
ScreenList.ClearAnnotation(); clearAnnotation( sheet.LastScreen(), nullptr );
} }
// Update the references for the sheet that is currently being displayed. // Update the references for the sheet that is currently being displayed.
@ -91,11 +107,9 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
REPORTER& aReporter ) REPORTER& aReporter )
{ {
SCH_REFERENCE_LIST references; SCH_REFERENCE_LIST references;
SCH_SCREENS screens( Schematic().Root() );
SCH_SCREENS screens( Schematic().Root() ); SCH_SHEET_LIST sheets = Schematic().GetSheets();
bool appendUndo = false;
// Build the sheet list.
SCH_SHEET_LIST sheets = Schematic().GetSheets();
// Map of locked components // Map of locked components
SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents; 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 it is an annotation for all the components, reset previous annotation.
if( aResetAnnotation ) if( aResetAnnotation )
DeleteAnnotation( !aAnnotateSchematic ); DeleteAnnotation( !aAnnotateSchematic, &appendUndo );
// Set sheet number and number of sheets. // Set sheet number and number of sheets.
SetSheetNumberAndCount(); SetSheetNumberAndCount();
@ -175,21 +189,25 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
// Recalculate and update reference numbers in schematic // Recalculate and update reference numbers in schematic
references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents ); references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
references.UpdateAnnotation();
for( size_t i = 0; i < references.GetCount(); i++ ) for( size_t i = 0; i < references.GetCount(); i++ )
{ {
SCH_COMPONENT* comp = references[ i ].GetComp(); SCH_REFERENCE& ref = references[i];
SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath(); SCH_COMPONENT* comp = ref.GetComp();
KIID_PATH curr_full_uuid = curr_sheetpath->Path(); SCH_SHEET_PATH* sheet = &ref.GetSheetPath();
curr_full_uuid.push_back( comp->m_Uuid );
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 ) if( comp->GetUnitCount() > 1 )
newRef << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) ); newRef << LIB_PART::SubReference( comp->GetUnitSelection( sheet ) );
wxString msg; wxString msg;
@ -202,11 +220,13 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
msg.Printf( _( "Updated %s (unit %s) from %s to %s" ), msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
comp->GetField( VALUE )->GetShownText(), comp->GetField( VALUE )->GetShownText(),
LIB_PART::SubReference( comp->GetUnit(), false ), LIB_PART::SubReference( comp->GetUnit(), false ),
prevRef, newRef ); prevRef,
newRef );
else else
msg.Printf( _( "Updated %s from %s to %s" ), msg.Printf( _( "Updated %s from %s to %s" ),
comp->GetField( VALUE )->GetShownText(), comp->GetField( VALUE )->GetShownText(),
prevRef, newRef ); prevRef,
newRef );
} }
else else
{ {

View File

@ -84,12 +84,13 @@ bool SCH_EDIT_FRAME::TestDanglingEnds()
bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd ) bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd )
{ {
bool retval = false; SCH_SCREEN* screen = GetScreen();
bool retval = false;
if( aStart == aEnd ) if( aStart == aEnd )
return retval; 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<SCH_LINE*>( item ); SCH_LINE* line = static_cast<SCH_LINE*>( 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 // Ensure that *line points to the segment containing aEnd
SCH_LINE* return_line = line; SCH_LINE* return_line = line;
BreakSegment( line, aStart, &return_line ); BreakSegment( line, aStart, &return_line );
if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aEnd ) ) if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aEnd ) )
line = return_line; line = return_line;
// Step 2: break the remaining segment. return_line remains line if not broken. // Step 2: break the remaining segment. return_line remains line if not broken.
// Ensure that *line _also_ contains aStart. This is our overlapping segment // Ensure that *line _also_ contains aStart. This is our overlapping segment
BreakSegment( line, aEnd, &return_line ); BreakSegment( line, aEnd, &return_line );
if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aStart ) ) if( IsPointOnSegment( return_line->GetStartPoint(), return_line->GetEndPoint(), aStart ) )
line = return_line; line = return_line;
SaveCopyInUndoList( line, UR_DELETED, true ); SaveCopyInUndoList( screen, line, UR_DELETED, true );
RemoveFromScreen( line ); RemoveFromScreen( line, screen );
retval = true; retval = true;
} }
@ -148,11 +151,12 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
if( aScreen == nullptr ) if( aScreen == nullptr )
aScreen = GetScreen(); aScreen = GetScreen();
auto remove_item = [&itemList, &deletedItems]( SCH_ITEM* aItem ) -> void { auto remove_item = [&itemList, &deletedItems, &aScreen]( SCH_ITEM* aItem ) -> void
aItem->SetFlags( STRUCT_DELETED ); {
itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) ); aItem->SetFlags( STRUCT_DELETED );
deletedItems.push_back( aItem ); itemList.PushItem( ITEM_PICKER( aScreen, aItem, UR_DELETED ) );
}; deletedItems.push_back( aItem );
};
BreakSegmentsOnJunctions( aScreen ); BreakSegmentsOnJunctions( aScreen );
@ -245,7 +249,7 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
{ {
remove_item( firstLine ); remove_item( firstLine );
remove_item( secondLine ); remove_item( secondLine );
itemList.PushItem( ITEM_PICKER( mergedLine, UR_NEW ) ); itemList.PushItem( ITEM_PICKER( aScreen, mergedLine, UR_NEW ) );
AddToScreen( mergedLine, aScreen ); AddToScreen( mergedLine, aScreen );
@ -288,8 +292,8 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
newSegment->SetStartPoint( aPoint ); newSegment->SetStartPoint( aPoint );
AddToScreen( newSegment, aScreen ); AddToScreen( newSegment, aScreen );
SaveCopyInUndoList( newSegment, UR_NEW, true ); SaveCopyInUndoList( aScreen, newSegment, UR_NEW, true );
SaveCopyInUndoList( aSegment, UR_CHANGED, true ); SaveCopyInUndoList( aScreen, aSegment, UR_CHANGED, true );
RefreshItem( aSegment ); RefreshItem( aSegment );
aSegment->SetEndPoint( aPoint ); aSegment->SetEndPoint( aPoint );
@ -362,11 +366,11 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
auto remove_item = [ & ]( SCH_ITEM* aItem ) -> void auto remove_item = [ & ]( SCH_ITEM* aItem ) -> void
{ {
aItem->SetFlags( STRUCT_DELETED ); aItem->SetFlags( STRUCT_DELETED );
undoList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) ); undoList.PushItem( ITEM_PICKER( screen, aItem, UR_DELETED ) );
}; };
remove_item( aJunction ); remove_item( aJunction );
RemoveFromScreen( aJunction ); RemoveFromScreen( aJunction, screen );
/// Note that std::list or similar is required here as we may insert values in the /// 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 /// 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( firstLine );
remove_item( secondLine ); remove_item( secondLine );
undoList.PushItem( ITEM_PICKER( line, UR_NEW ) ); undoList.PushItem( ITEM_PICKER( screen, line, UR_NEW ) );
AddToScreen( line ); AddToScreen( line, screen );
if( line->IsSelected() ) if( line->IsSelected() )
selectionTool->AddItemToSel( line, true /*quiet mode*/ ); selectionTool->AddItemToSel( line, true /*quiet mode*/ );
@ -421,18 +425,19 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
if( line->IsSelected() ) if( line->IsSelected() )
selectionTool->RemoveItemFromSel( line, true /*quiet mode*/ ); 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 ); SCH_JUNCTION* junction = new SCH_JUNCTION( aPos );
AddToScreen( junction ); AddToScreen( junction, aScreen );
SaveCopyInUndoList( junction, UR_NEW, aUndoAppend ); SaveCopyInUndoList( aScreen, junction, UR_NEW, aUndoAppend );
BreakSegments( aPos ); BreakSegments( aPos );
if( aFinal ) if( aFinal )

View File

@ -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. * This program source code file is part of KiCad, a free EDA CAD application.
* *
@ -30,11 +25,8 @@
#include <fctsys.h> #include <fctsys.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_draw_panel.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <confirm.h> #include <confirm.h>
#include <invoke_sch_dialog.h>
#include <dialog_annotate_base.h> #include <dialog_annotate_base.h>
#include <eeschema_settings.h> #include <eeschema_settings.h>
#include <kiface_i.h> #include <kiface_i.h>
@ -59,7 +51,7 @@ private:
/// Initialises member variables /// Initialises member variables
void InitValues(); void InitValues();
void OnClearAnnotationCmpClick( wxCommandEvent& event ) override; void OnClearAnnotationClick( wxCommandEvent& event ) override;
void OnCloseClick( wxCommandEvent& event ) override; void OnCloseClick( wxCommandEvent& event ) override;
void OnClose( wxCloseEvent& event ) override; void OnClose( wxCloseEvent& event ) override;
void OnApplyClick( wxCommandEvent& event ) override; void OnApplyClick( wxCommandEvent& event ) override;
@ -132,7 +124,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
void DIALOG_ANNOTATE::InitValues() void DIALOG_ANNOTATE::InitValues()
{ {
auto cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ); EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
int option; int option;
// These are always reset to attempt to keep the user out of trouble... // These are always reset to attempt to keep the user out of trouble...
@ -144,12 +136,8 @@ void DIALOG_ANNOTATE::InitValues()
switch( option ) switch( option )
{ {
default: default:
case 0: case 0: m_rbSortBy_X_Position->SetValue( true ); break;
m_rbSortBy_X_Position->SetValue( true ); case 1: m_rbSortBy_Y_Position->SetValue( true ); break;
break;
case 1:
m_rbSortBy_Y_Position->SetValue( true );
break;
} }
option = cfg->m_AnnotatePanel.method; option = cfg->m_AnnotatePanel.method;
@ -157,15 +145,9 @@ void DIALOG_ANNOTATE::InitValues()
switch( option ) switch( option )
{ {
default: default:
case 0: case 0: m_rbFirstFree->SetValue( true ); break;
m_rbFirstFree->SetValue( true ); case 1: m_rbSheetX100->SetValue( true ); break;
break; case 2: m_rbSheetX1000->SetValue( true ); break;
case 1:
m_rbSheetX100->SetValue( true );
break;
case 2:
m_rbSheetX1000->SetValue( true );
break;
} }
m_textNumberAfter->SetValue( wxT( "0" ) ); m_textNumberAfter->SetValue( wxT( "0" ) );
@ -194,26 +176,6 @@ void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event )
void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& 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(); m_MessageWindow->Clear();
REPORTER& reporter = m_MessageWindow->Reporter(); REPORTER& reporter = m_MessageWindow->Reporter();
m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message 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(), (ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(),
GetResetItems() , true, GetLockUnits(), reporter ); 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(); 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() ) m_Parent->DeleteAnnotation( !GetLevel(), &appendUndo );
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_btnClear->Enable( false ); m_btnClear->Enable( false );
} }

View File

@ -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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // 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->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); 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 ); 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 = 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 ); fgSizer1->Add( m_rbScope, 0, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer1; wxStaticBoxSizer* sbSizer1;
@ -148,7 +148,7 @@ DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, con
// Connect Events // Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) ); 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_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 ); 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 // Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) ); 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_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 ); m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this );

View File

@ -14,7 +14,6 @@
<property name="file">dialog_annotate_base</property> <property name="file">dialog_annotate_base</property>
<property name="first_id">1000</property> <property name="first_id">1000</property>
<property name="help_provider">none</property> <property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property> <property name="indent_with_spaces"></property>
<property name="internationalize">1</property> <property name="internationalize">1</property>
<property name="name">dialog_annotate_base</property> <property name="name">dialog_annotate_base</property>
@ -26,7 +25,6 @@
<property name="skip_php_events">1</property> <property name="skip_php_events">1</property>
<property name="skip_python_events">1</property> <property name="skip_python_events">1</property>
<property name="ui_table">UI</property> <property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property> <property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property> <property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1"> <object class="Dialog" expanded="1">
@ -165,7 +163,7 @@
<property name="caption"></property> <property name="caption"></property>
<property name="caption_visible">1</property> <property name="caption_visible">1</property>
<property name="center_pane">0</property> <property name="center_pane">0</property>
<property name="choices">&quot;Use the entire schematic&quot; &quot;Use the current page only&quot;</property> <property name="choices">&quot;Entire schematic&quot; &quot;Current sheet only&quot;</property>
<property name="close_button">1</property> <property name="close_button">1</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
@ -197,7 +195,7 @@
<property name="pin_button">1</property> <property name="pin_button">1</property>
<property name="pos"></property> <property name="pos"></property>
<property name="resize">Resizable</property> <property name="resize">Resizable</property>
<property name="selection">0</property> <property name="selection">1</property>
<property name="show">1</property> <property name="show">1</property>
<property name="size"></property> <property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property> <property name="style">wxRA_SPECIFY_COLS</property>
@ -1018,7 +1016,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<event name="OnButtonClick">OnClearAnnotationCmpClick</event> <event name="OnButtonClick">OnClearAnnotationClick</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">

View File

@ -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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // 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 event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } 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 OnCloseClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); }

View File

@ -415,7 +415,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
// save old cmp in undo list if not already in edit, or moving ... // save old cmp in undo list if not already in edit, or moving ...
if( m_cmp->GetEditFlags() == 0 ) 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 // Save current flags which could be modified by next change settings
STATUS_FLAGS flags = m_cmp->GetFlags(); 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. // should be kept in sync in multi-unit parts.
if( m_cmp->GetUnitCount() > 1 ) if( m_cmp->GetUnitCount() > 1 )
{ {
std::vector<SCH_COMPONENT*> otherUnits; for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
CollectOtherUnits( GetParent()->GetCurrentSheet(), m_cmp, &otherUnits );
for( SCH_COMPONENT* otherUnit : otherUnits )
{ {
GetParent()->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */); SCH_SCREEN* screen = sheet.LastScreen();
otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() ); std::vector<SCH_COMPONENT*> otherUnits;
otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() );
otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() ); CollectOtherUnits( sheet, m_cmp, &otherUnits );
otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() ); for( SCH_COMPONENT* otherUnit : otherUnits )
GetParent()->RefreshItem( otherUnit ); {
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() ); copy.SetLibSymbol( libSymbol->Flatten().release() );
// Update the requested fields in the component copy // Update the requested fields in the component copy
std::list<SCH_COMPONENT*> components; InvokeDialogUpdateFields( GetParent(), &copy, false );
components.push_back( &copy );
InvokeDialogUpdateFields( GetParent(), components, false );
wxGridTableMessage clear( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, m_fields->size() ); wxGridTableMessage clear( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, m_fields->size() );
m_grid->ProcessTableMessage( clear ); m_grid->ProcessTableMessage( clear );

View File

@ -395,7 +395,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow()
/* save old text in undo list if not already in edit */ /* save old text in undo list if not already in edit */
if( m_CurrentText->GetEditFlags() == 0 ) 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(); m_Parent->GetCanvas()->Refresh();

View File

@ -211,10 +211,10 @@ bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow()
PICKED_ITEMS_LIST pickedItems; PICKED_ITEMS_LIST pickedItems;
STROKE_PARAMS stroke; STROKE_PARAMS stroke;
for( auto& strokeItem : m_strokeItems ) for( SCH_ITEM* strokeItem : m_strokeItems )
pickedItems.PushItem( ITEM_PICKER( strokeItem, UR_CHANGED ) ); 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 ) for( auto& strokeItem : m_strokeItems )
{ {

View File

@ -405,22 +405,26 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH*
aField->SetText( m_text ); aField->SetText( m_text );
updateText( aField ); updateText( aField );
// The value, footprint and datasheet fields should be kept in sync in multi-unit // The value, footprint and datasheet fields should be kept in sync in multi-unit parts.
// parts.
// Of course the component must be annotated to collect other units. // Of course the component must be annotated to collect other units.
if( editFrame && parent && parent->Type() == SCH_COMPONENT_T if( editFrame && parent && parent->Type() == SCH_COMPONENT_T
&& ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) ) && ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) )
{ {
SCH_COMPONENT* thisUnit = static_cast<SCH_COMPONENT*>( parent ); SCH_COMPONENT* thisUnit = static_cast<SCH_COMPONENT*>( parent );
std::vector<SCH_COMPONENT*> otherUnits;
CollectOtherUnits( editFrame->GetCurrentSheet(), thisUnit, &otherUnits ); for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() )
for( SCH_COMPONENT* otherUnit : otherUnits )
{ {
editFrame->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */); SCH_SCREEN* screen = sheet.LastScreen();
otherUnit->GetField( fieldType )->SetText( m_text ); std::vector<SCH_COMPONENT*> otherUnits;
editFrame->RefreshItem( otherUnit );
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 );
}
} }
} }

View File

@ -97,7 +97,10 @@ bool DIALOG_EDIT_SHEET_PIN::TransferDataToWindow()
bool DIALOG_EDIT_SHEET_PIN::TransferDataFromWindow() bool DIALOG_EDIT_SHEET_PIN::TransferDataFromWindow()
{ {
if( !m_sheetPin->IsNew() ) 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 ) ); m_sheetPin->SetText( EscapeString( m_comboName->GetValue(), CTX_NETNAME ) );
// Currently, eeschema uses only the text width as text size, // Currently, eeschema uses only the text width as text size,

View File

@ -600,9 +600,9 @@ public:
for( unsigned i = 0; i < m_componentRefs.GetCount(); ++i ) for( unsigned i = 0; i < m_componentRefs.GetCount(); ++i )
{ {
SCH_COMPONENT& comp = *m_componentRefs[i].GetComp(); 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( screen, &comp, UR_CHANGED, true );
m_frame->SaveCopyInUndoList( &comp, UR_CHANGED, true );
const std::map<wxString, wxString>& fieldStore = m_dataStore[comp.m_Uuid]; const std::map<wxString, wxString>& fieldStore = m_dataStore[comp.m_Uuid];

View File

@ -218,7 +218,7 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aS
auto sch_text = dynamic_cast<SCH_TEXT*>( aItem ); auto sch_text = dynamic_cast<SCH_TEXT*>( aItem );
auto lineItem = dynamic_cast<SCH_LINE*>( aItem ); auto lineItem = dynamic_cast<SCH_LINE*>( aItem );
m_parent->SaveCopyInUndoList( aItem, UR_CHANGED, m_hasChange ); m_parent->SaveCopyInUndoList( aSheetPath.LastScreen(), aItem, UR_CHANGED, m_hasChange );
if( eda_text ) if( eda_text )
{ {

View File

@ -171,10 +171,10 @@ bool DIALOG_JUNCTION_PROPS::TransferDataFromWindow()
{ {
PICKED_ITEMS_LIST pickedItems; PICKED_ITEMS_LIST pickedItems;
for( auto& junction : m_junctions ) for( SCH_JUNCTION* junction : m_junctions )
pickedItems.PushItem( ITEM_PICKER( junction, UR_CHANGED ) ); 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 ) for( auto& junction : m_junctions )
{ {

View File

@ -481,7 +481,7 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam
} }
if( isUndoable ) if( isUndoable )
m_frame->SaveCopyInUndoList( m_sheet, UR_CHANGED ); m_frame->SaveCopyInUndoList( m_frame->GetScreen(), m_sheet, UR_CHANGED, false );
if( renameFile ) if( renameFile )
{ {

View File

@ -99,7 +99,7 @@ void DIALOG_SYMBOL_REMAP::OnRemapSymbols( wxCommandEvent& aEvent )
if( viewer ) if( viewer )
viewer->ReCreateListLib(); viewer->ReCreateListLib();
parent->GetScreen()->ClearUndoORRedoList( parent->GetScreen()->m_UndoList, 1 ); parent->ClearUndoORRedoList( parent->m_UndoList, 1 );
parent->SyncView(); parent->SyncView();
parent->GetCanvas()->Refresh(); parent->GetCanvas()->Refresh();
parent->OnModify(); parent->OnModify();

View File

@ -28,23 +28,41 @@
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_component.h> #include <sch_component.h>
#include <schematic.h>
#include <class_libentry.h> #include <class_libentry.h>
#include <algorithm> #include <algorithm>
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, SCH_COMPONENT* aSpecificComponent,
const list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry ) bool aCreateUndoEntry )
{ {
DIALOG_UPDATE_FIELDS dlg( aCaller, aComponents, aCreateUndoEntry ); DIALOG_UPDATE_FIELDS dlg( aCaller, aSpecificComponent, aCreateUndoEntry );
return dlg.ShowQuasiModal(); return dlg.ShowQuasiModal();
} }
DIALOG_UPDATE_FIELDS::DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, DIALOG_UPDATE_FIELDS::DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent,
const list<SCH_COMPONENT*>& aComponents, bool aCreateUndoEntry ) SCH_COMPONENT* aSpecificComponent,
: DIALOG_UPDATE_FIELDS_BASE( aParent ), m_frame( aParent ), bool aCreateUndoEntry ) :
m_components( aComponents ), m_createUndo( 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<SCH_COMPONENT*>( item ) );
}
}
m_sdbSizerOK->SetDefault(); m_sdbSizerOK->SetDefault();
} }
@ -57,7 +75,6 @@ bool DIALOG_UPDATE_FIELDS::TransferDataFromWindow()
if( m_components.empty() ) if( m_components.empty() )
return true; // nothing to process return true; // nothing to process
// Create the set of fields to be updated // Create the set of fields to be updated
m_updateFields.clear(); m_updateFields.clear();
@ -73,16 +90,16 @@ bool DIALOG_UPDATE_FIELDS::TransferDataFromWindow()
{ {
PICKED_ITEMS_LIST itemsList; PICKED_ITEMS_LIST itemsList;
for( auto component : m_components ) for( std::pair<SCH_SCREEN*, SCH_COMPONENT*>& component : m_components )
itemsList.PushItem( ITEM_PICKER( component, UR_CHANGED ) ); 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! // Do it!
for( auto component : m_components ) for( std::pair<SCH_SCREEN*, SCH_COMPONENT*>& component : m_components )
updateFields( component ); updateFields( component.second );
m_frame->SyncView(); m_frame->SyncView();
m_frame->GetCanvas()->Refresh(); 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 // Collect all user field names from library parts of components that are going to be updated
{ {
for( auto component : m_components ) for( std::pair<SCH_SCREEN*, SCH_COMPONENT*>& component : m_components )
{ {
const std::unique_ptr< LIB_PART >& part = component->GetPartRef(); const std::unique_ptr< LIB_PART >& part = component.second->GetPartRef();
if( !part ) if( !part )
continue; continue;
@ -123,7 +140,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow()
for( int i = 0; i < MANDATORY_FIELDS; ++i ) 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 ) if( i != REFERENCE && i != VALUE )
m_fieldsBox->Check( i, true ); m_fieldsBox->Check( i, true );

View File

@ -34,17 +34,14 @@ class SCH_COMPONENT;
class SCH_SCREEN; class SCH_SCREEN;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
using std::set;
using std::list;
/** /**
* Dialog to update component fields (i.e. restore them from the original library symbols). * Dialog to update component fields (i.e. restore them from the original library symbols).
*/ */
class DIALOG_UPDATE_FIELDS : public DIALOG_UPDATE_FIELDS_BASE class DIALOG_UPDATE_FIELDS : public DIALOG_UPDATE_FIELDS_BASE
{ {
public: public:
DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, const list<SCH_COMPONENT*>& aComponents, DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, SCH_COMPONENT* aComponent,
bool aCreateUndoEntry = true ); bool aCreateUndoEntry );
private: private:
bool TransferDataFromWindow() override; bool TransferDataFromWindow() override;
@ -66,16 +63,14 @@ private:
checkAll( false ); checkAll( false );
} }
///> Parent frame
SCH_EDIT_FRAME* m_frame; SCH_EDIT_FRAME* m_frame;
///> Set of field names that should have values updated ///> Set of field names that should have values updated
set<wxString> m_updateFields; std::set<wxString> m_updateFields;
///> Components to update ///> Components to update
list<SCH_COMPONENT*> m_components; std::vector< std::pair<SCH_SCREEN*, SCH_COMPONENT*>> m_components;
///> Flag indicating whether an undo buffer entry should be created
bool m_createUndo; bool m_createUndo;
}; };

View File

@ -492,7 +492,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet. GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
RecalculateConnections( GLOBAL_CLEANUP ); RecalculateConnections( GLOBAL_CLEANUP );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 ); ClearUndoRedoList();
GetScreen()->m_Initialized = true; 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. // Only perform the dangling end test on root sheet.
GetScreen()->TestDanglingEnds(); GetScreen()->TestDanglingEnds();
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 ); ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
SetSheetNumberAndCount(); SetSheetNumberAndCount();

View File

@ -211,7 +211,7 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_COMPONENT* aComponent, int aUnit )
STATUS_FLAGS savedFlags = aComponent->GetFlags(); STATUS_FLAGS savedFlags = aComponent->GetFlags();
if( !aComponent->GetEditFlags() ) // No command in progress: save in undo list 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. */ /* Update the unit number. */
aComponent->SetUnitSelection( &GetCurrentSheet(), aUnit ); aComponent->SetUnitSelection( &GetCurrentSheet(), aUnit );

View File

@ -245,7 +245,6 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
{ {
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
screen->m_Initialized = true; screen->m_Initialized = true;
screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
} }
else else
{ {

View File

@ -86,8 +86,8 @@ int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller ); void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller );
/// Update symbol fields /// Update symbol fields
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, SCH_COMPONENT* aSpecificComponent = nullptr,
const std::list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry ); bool aCreateUndoEntry = true );
/** /**
* Create and shows NETLIST_DIALOG and returns whatever * Create and shows NETLIST_DIALOG and returns whatever

View File

@ -117,7 +117,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_dummyScreen = new SCH_SCREEN(); m_dummyScreen = new SCH_SCREEN();
SetScreen( m_dummyScreen ); SetScreen( m_dummyScreen );
GetScreen()->m_Center = true; GetScreen()->m_Center = true;
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false ); GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
@ -726,7 +725,7 @@ void LIB_EDIT_FRAME::emptyScreen()
SetCurLib( wxEmptyString ); SetCurLib( wxEmptyString );
SetCurPart( nullptr ); SetCurPart( nullptr );
SetScreen( m_dummyScreen ); SetScreen( m_dummyScreen );
m_dummyScreen->ClearUndoRedoList(); ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
Refresh(); Refresh();
} }
@ -909,3 +908,20 @@ bool LIB_EDIT_FRAME::IsContentModified()
return false; 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();
}

View File

@ -342,6 +342,20 @@ public:
void RollbackPartFromUndo(); 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: private:
/** /**
* Read a component symbol file (*.sym ) and add graphic items to the current component. * Read a component symbol file (*.sym ) and add graphic items to the current component.

View File

@ -186,7 +186,7 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, in
// Enable synchronized pin edit mode for symbols with interchangeable units // Enable synchronized pin edit mode for symbols with interchangeable units
m_SyncPinEdit = !GetCurPart()->UnitsLocked(); m_SyncPinEdit = !GetCurPart()->UnitsLocked();
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() ); SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );

View File

@ -41,34 +41,34 @@ void LIB_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* ItemToCopy, UNDO_REDO_T undoT
if( !ItemToCopy ) if( !ItemToCopy )
return; return;
LIB_PART* CopyItem; LIB_PART* copyItem;
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); 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). // Clear current flags (which can be temporary set by a current edit command).
CopyItem->ClearTempFlags(); copyItem->ClearTempFlags();
CopyItem->ClearEditFlags(); copyItem->ClearEditFlags();
CopyItem->SetFlags( UR_TRANSIENT ); copyItem->SetFlags( UR_TRANSIENT );
ITEM_PICKER wrapper( CopyItem, undoType ); ITEM_PICKER wrapper( GetScreen(), copyItem, undoType );
lastcmd->PushItem( wrapper ); lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd ); PushCommandToUndoList( lastcmd );
// Clear redo list, because after new save there is no redo to do. // 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() void LIB_EDIT_FRAME::GetComponentFromRedoList()
{ {
if( GetScreen()->GetRedoCommandCount() <= 0 ) if( GetRedoCommandCount() <= 0 )
return; return;
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
// Load the last redo entry // Load the last redo entry
PICKED_ITEMS_LIST* redoCommand = GetScreen()->PopCommandFromRedoList(); PICKED_ITEMS_LIST* redoCommand = PopCommandFromRedoList();
ITEM_PICKER redoWrapper = redoCommand->PopItem(); ITEM_PICKER redoWrapper = redoCommand->PopItem();
delete redoCommand; delete redoCommand;
LIB_PART* part = (LIB_PART*) redoWrapper.GetItem(); LIB_PART* part = (LIB_PART*) redoWrapper.GetItem();
@ -80,9 +80,9 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList()
PICKED_ITEMS_LIST* undoCommand = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* undoCommand = new PICKED_ITEMS_LIST();
LIB_PART* oldPart = m_my_part; LIB_PART* oldPart = m_my_part;
oldPart->SetFlags( UR_TRANSIENT ); oldPart->SetFlags( UR_TRANSIENT );
ITEM_PICKER undoWrapper( oldPart, undoRedoType ); ITEM_PICKER undoWrapper( GetScreen(), oldPart, undoRedoType );
undoCommand->PushItem( undoWrapper ); undoCommand->PushItem( undoWrapper );
GetScreen()->PushCommandToUndoList( undoCommand ); PushCommandToUndoList( undoCommand );
// Do not delete the previous part by calling SetCurPart( part ) // Do not delete the previous part by calling SetCurPart( part )
// which calls delete <previous part>. // which calls delete <previous part>.
@ -110,13 +110,13 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList()
void LIB_EDIT_FRAME::GetComponentFromUndoList() void LIB_EDIT_FRAME::GetComponentFromUndoList()
{ {
if( GetScreen()->GetUndoCommandCount() <= 0 ) if( GetUndoCommandCount() <= 0 )
return; return;
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
// Load the last undo entry // Load the last undo entry
PICKED_ITEMS_LIST* undoCommand = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* undoCommand = PopCommandFromUndoList();
ITEM_PICKER undoWrapper = undoCommand->PopItem(); ITEM_PICKER undoWrapper = undoCommand->PopItem();
delete undoCommand; delete undoCommand;
LIB_PART* part = (LIB_PART*) undoWrapper.GetItem(); LIB_PART* part = (LIB_PART*) undoWrapper.GetItem();
@ -128,9 +128,9 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList()
PICKED_ITEMS_LIST* redoCommand = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* redoCommand = new PICKED_ITEMS_LIST();
LIB_PART* oldPart = m_my_part; LIB_PART* oldPart = m_my_part;
oldPart->SetFlags( UR_TRANSIENT ); oldPart->SetFlags( UR_TRANSIENT );
ITEM_PICKER redoWrapper( oldPart, undoRedoType ); ITEM_PICKER redoWrapper( GetScreen(), oldPart, undoRedoType );
redoCommand->PushItem( redoWrapper ); redoCommand->PushItem( redoWrapper );
GetScreen()->PushCommandToRedoList( redoCommand ); PushCommandToRedoList( redoCommand );
// Do not delete the previous part by calling SetCurPart( part ), // Do not delete the previous part by calling SetCurPart( part ),
// which calls delete <previous part>. // which calls delete <previous part>.
@ -161,7 +161,7 @@ void LIB_EDIT_FRAME::RollbackPartFromUndo()
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
// Load the last undo entry // 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 // Check if we were already at the top of the stack
if( !undoCommand ) if( !undoCommand )

View File

@ -95,10 +95,10 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { 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 ) { 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 ) { auto haveSymbolCondition = [ this ] ( const SELECTION& sel ) {
return m_my_part != nullptr; return m_my_part != nullptr;

View File

@ -158,10 +158,8 @@ void LIB_EDIT_FRAME::SyncToolbars()
bool isEditable = m_my_part && m_my_part->IsRoot(); bool isEditable = m_my_part && m_my_part->IsRoot();
m_mainToolBar->Toggle( ACTIONS::saveAll, m_libMgr->HasModifications() ); m_mainToolBar->Toggle( ACTIONS::saveAll, m_libMgr->HasModifications() );
m_mainToolBar->Toggle( ACTIONS::undo, m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo,
GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) ); m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) );
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, (bool) m_my_part ); m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, (bool) m_my_part );
m_mainToolBar->Toggle( EE_ACTIONS::runERC, isEditable ); m_mainToolBar->Toggle( EE_ACTIONS::runERC, isEditable );

View File

@ -132,10 +132,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; return GetUndoCommandCount() > 0;
}; };
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; return GetRedoCommandCount() > 0;
}; };
editMenu->AddItem( ACTIONS::undo, enableUndoCondition ); editMenu->AddItem( ACTIONS::undo, enableUndoCondition );

View File

@ -249,13 +249,13 @@ public:
* Add an item to the screen (and view) * Add an item to the screen (and view)
* aScreen is the screen the item is located on, if not the current screen * 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) * Remove an item from the screen (and view)
* aScreen is the screen the item is located on, if not the current screen * 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. * Mark an item for refresh.

View File

@ -424,7 +424,6 @@ void SCH_EDIT_FRAME::CreateScreens()
m_defaults = &m_schematic->Settings(); m_defaults = &m_schematic->Settings();
SCH_SCREEN* rootScreen = new SCH_SCREEN( m_schematic ); SCH_SCREEN* rootScreen = new SCH_SCREEN( m_schematic );
rootScreen->SetMaxUndoItems( m_UndoRedoCountMax );
m_schematic->Root().SetScreen( rootScreen ); m_schematic->Root().SetScreen( rootScreen );
SetScreen( Schematic().RootScreen() ); SetScreen( Schematic().RootScreen() );
@ -433,7 +432,6 @@ void SCH_EDIT_FRAME::CreateScreens()
if( GetScreen() == NULL ) if( GetScreen() == NULL )
{ {
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic ); SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
screen->SetMaxUndoItems( m_UndoRedoCountMax );
SetScreen( screen ); 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." ) ); wxCHECK_RET( aItem != NULL, wxT( "Cannot add null item to list." ) );
SCH_SHEET* parentSheet = nullptr; 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 ) if( aItem->Type() == SCH_SHEET_PIN_T )
{ {
// Sheet pins are owned by their parent sheet. // 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 ); parentSheet->AddPin( (SCH_SHEET_PIN*) aItem );
} }
@ -938,11 +935,11 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe
} }
else else
{ {
if( !screen->CheckIfOnDrawList( aItem ) ) // don't want a loop! if( !aScreen->CheckIfOnDrawList( aItem ) ) // don't want a loop!
AddToScreen( aItem ); AddToScreen( aItem, aScreen );
SaveCopyForRepeatItem( aItem ); SaveCopyForRepeatItem( aItem );
SaveCopyInUndoList( undoItem, UR_NEW, aUndoAppend ); SaveCopyInUndoList( aScreen, undoItem, UR_NEW, aUndoAppend );
} }
// Update connectivity info for new item // Update connectivity info for new item
@ -952,7 +949,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe
aItem->ClearFlags( IS_NEW ); aItem->ClearFlags( IS_NEW );
screen->SetModify(); aScreen->SetModify();
RefreshItem( aItem ); RefreshItem( aItem );
if( !aItem->IsMoving() && aItem->IsConnectable() ) 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++ ) for( auto j = i + 1; j != pts.end(); j++ )
TrimWire( *i, *j ); TrimWire( *i, *j );
if( screen->IsJunctionNeeded( *i, true ) ) if( aScreen->IsJunctionNeeded( *i, true ) )
AddJunction( *i, true, false ); AddJunction( aScreen, *i, true, false );
} }
TestDanglingEnds(); TestDanglingEnds();
@ -1104,7 +1101,7 @@ void SCH_EDIT_FRAME::FixupJunctions()
SetCurrentSheet( sheet ); SetCurrentSheet( sheet );
GetCurrentSheet().UpdateAllScreenReferences(); GetCurrentSheet().UpdateAllScreenReferences();
auto screen = GetCurrentSheet().LastScreen(); SCH_SCREEN* screen = GetCurrentSheet().LastScreen();
for( auto aItem : screen->Items().OfType( SCH_COMPONENT_T ) ) for( auto aItem : screen->Items().OfType( SCH_COMPONENT_T ) )
{ {
@ -1120,8 +1117,8 @@ void SCH_EDIT_FRAME::FixupJunctions()
} }
} }
for( auto& pos : junctions ) for( const wxPoint& pos : junctions )
AddJunction( pos, false, false ); AddJunction( screen, pos, false, false );
if( junctions.size() ) if( junctions.size() )
modified = true; modified = true;

View File

@ -259,7 +259,7 @@ public:
* Add an item to the schematic and adds the changes to the undo/redo container. * 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. * @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. * Run the Find or Find & Replace dialog.
@ -423,7 +423,7 @@ public:
* @param aCurrentSheetOnly Clear only the annotation for the current sheet if true. * @param aCurrentSheetOnly Clear only the annotation for the current sheet if true.
* Otherwise clear the entire schematic annotation. * 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. * Annotate the components in the schematic that are not currently annotated.
@ -572,7 +572,7 @@ public:
*/ */
bool AskToSaveChanges(); 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 ); bool aFinal = true );
/** /**
@ -792,7 +792,7 @@ public:
/** /**
* Create a copy of the current schematic item, and put it in the undo list. * Create a copy of the current schematic item, and put it in the undo list.
* *
* flag_type_command = * aTypeCommand =
* UR_CHANGED * UR_CHANGED
* UR_NEW * UR_NEW
* UR_DELETED * UR_DELETED
@ -804,21 +804,19 @@ public:
* *
* @note * @note
* Edit wires and buses is a bit complex. * Edit wires and buses is a bit complex.
* because when a new wire is added, a lot of modifications in wire list is made * When a new wire is added, a lot of modifications are made in the wire list (merging,
* (wire concatenation): modified items, deleted items and new items * junctions, etc.). We therefore set the aTypeCommand to UR_WIRE_IMAGE and save the whole
* so flag_type_command is UR_WIRE_IMAGE: the struct ItemToCopy is a list of * schebang.
* wires saved in Undo List (for Undo or Redo commands, saved wires will be
* exchanged with current wire list
* *
* @param aItemToCopy = the schematic item modified by the command to undo * @param aItemToCopy = the schematic item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T) * @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aAppend = add the item to the previous undo list * @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation for commands like move
* for commands like move
*/ */
void SaveCopyInUndoList( SCH_ITEM* aItemToCopy, void SaveCopyInUndoList( SCH_SCREEN* aScreen,
SCH_ITEM* aItemToCopy,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
bool aAppend = false, bool aAppend,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/** /**
@ -827,12 +825,11 @@ public:
* @param aItemsList = the list of items modified by the command to undo * @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T) * @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aAppend = add the item to the previous undo list * @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation for commands like move
* for commands like move
*/ */
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
bool aAppend = false, bool aAppend,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/** /**
@ -843,6 +840,20 @@ public:
*/ */
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand ); 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. * Clone \a aItem and owns that clone in this container.
*/ */

View File

@ -85,7 +85,6 @@ SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) :
SCH_SCREEN::~SCH_SCREEN() SCH_SCREEN::~SCH_SCREEN()
{ {
clearLibSymbols(); clearLibSymbols();
ClearUndoRedoList();
FreeDrawList(); 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() void SCH_SCREEN::ClearDrawingState()
{ {
for( auto item : Items() ) 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 ) void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList )
{ {
SCH_SCREEN* first = GetFirst(); SCH_SCREEN* first = GetFirst();

View File

@ -330,24 +330,6 @@ public:
*/ */
std::set<SCH_ITEM*> MarkConnections( SCH_LINE* aSegment ); std::set<SCH_ITEM*> 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. * Clear the state flags of all the items in the screen.
*/ */
@ -560,11 +542,6 @@ public:
SCH_SCREEN* GetScreen( unsigned int aIndex ) const; SCH_SCREEN* GetScreen( unsigned int aIndex ) const;
SCH_SHEET* GetSheet( 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 * Clear the annotation for the components inside new sheetpaths
* when a complex hierarchy is modified and new sheetpaths added * when a complex hierarchy is modified and new sheetpaths added

View File

@ -23,26 +23,17 @@
*/ */
#include <fctsys.h> #include <fctsys.h>
#include <sch_draw_panel.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <general.h>
#include <sch_bus_entry.h> #include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_junction.h> #include <sch_junction.h>
#include <sch_line.h> #include <sch_line.h>
#include <sch_no_connect.h>
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_bitmap.h> #include <sch_bitmap.h>
#include <sch_view.h>
#include <tools/ee_selection_tool.h> #include <tools/ee_selection_tool.h>
#include <ws_proxy_undo_item.h> #include <ws_proxy_undo_item.h>
#include <tool/actions.h> #include <tool/actions.h>
/* Functions to undo and redo edit commands. /* 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 * 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), * 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 * 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, UNDO_REDO_T aCommandType,
bool aAppend, bool aAppend,
const wxPoint& aTransformPoint ) const wxPoint& aTransformPoint )
@ -117,7 +109,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
aItem->SetConnectivityDirty(); aItem->SetConnectivityDirty();
if( aAppend ) if( aAppend )
commandToUndo = GetScreen()->PopCommandFromUndoList(); commandToUndo = PopCommandFromUndoList();
if( !commandToUndo ) if( !commandToUndo )
{ {
@ -125,7 +117,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
commandToUndo->m_TransformPoint = aTransformPoint; commandToUndo->m_TransformPoint = aTransformPoint;
} }
ITEM_PICKER itemWrapper( aItem, aCommandType ); ITEM_PICKER itemWrapper( aScreen, aItem, aCommandType );
itemWrapper.SetFlags( aItem->GetFlags() ); itemWrapper.SetFlags( aItem->GetFlags() );
switch( aCommandType ) switch( aCommandType )
@ -151,10 +143,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
if( commandToUndo->GetCount() ) if( commandToUndo->GetCount() )
{ {
/* Save the copy in undo list */ /* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo ); PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */ /* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); ClearUndoORRedoList( m_RedoList );
} }
else 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 // Can't append a WIRE IMAGE, so fail to a new undo point
if( aAppend ) if( aAppend )
commandToUndo = GetScreen()->PopCommandFromUndoList(); commandToUndo = PopCommandFromUndoList();
if( !commandToUndo ) if( !commandToUndo )
{ {
@ -247,10 +239,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
if( commandToUndo->GetCount() ) if( commandToUndo->GetCount() )
{ {
/* Save the copy in undo list */ /* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo ); PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */ /* 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 else // Should not occur
{ {
@ -275,13 +267,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( status == UR_NEW ) if( status == UR_NEW )
{ {
// new items are deleted on undo // new items are deleted on undo
RemoveFromScreen( eda_item ); RemoveFromScreen( eda_item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
aList->SetPickedItemStatus( UR_DELETED, (unsigned) ii ); aList->SetPickedItemStatus( UR_DELETED, (unsigned) ii );
} }
else if( status == UR_DELETED ) else if( status == UR_DELETED )
{ {
// deleted items are re-inserted on undo // 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 ); aList->SetPickedItemStatus( UR_NEW, (unsigned) ii );
} }
else if( status == UR_PAGESETTINGS ) 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* item = (SCH_ITEM*) eda_item;
SCH_ITEM* alt_item = (SCH_ITEM*) aList->GetPickedItemLink( (unsigned) ii ); SCH_ITEM* alt_item = (SCH_ITEM*) aList->GetPickedItemLink( (unsigned) ii );
RemoveFromScreen( item ); RemoveFromScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
switch( status ) switch( status )
{ {
@ -343,7 +335,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
break; 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() void SCH_EDIT_FRAME::RollbackSchematicFromUndo()
{ {
PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* undo = PopCommandFromUndoList();
if( undo ) if( undo )
{ {
@ -375,3 +367,20 @@ void SCH_EDIT_FRAME::RollbackSchematicFromUndo()
SyncView(); SyncView();
GetCanvas()->Refresh(); 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();
}

View File

@ -96,7 +96,6 @@ void SCH_EDIT_FRAME::InitSheet( SCH_SHEET* aSheet, const wxString& aNewFilename
{ {
aSheet->SetScreen( new SCH_SCREEN( &Schematic() ) ); aSheet->SetScreen( new SCH_SCREEN( &Schematic() ) );
aSheet->GetScreen()->SetModify(); aSheet->GetScreen()->SetModify();
aSheet->GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
aSheet->GetScreen()->SetFileName( aNewFilename ); aSheet->GetScreen()->SetFileName( aNewFilename );
} }

View File

@ -172,8 +172,8 @@ void SCH_EDIT_FRAME::SyncToolbars()
m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );
m_mainToolBar->Refresh(); m_mainToolBar->Refresh();

View File

@ -47,7 +47,8 @@ BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter,
m_ignoreOtherProjects( aIgnoreOtherProjects ), m_ignoreOtherProjects( aIgnoreOtherProjects ),
m_dryRun( aDryRun ), m_dryRun( aDryRun ),
m_frame( aFrame ), 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 ) bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
{ {
m_changesCount = 0; m_changesCount = 0;
m_appendUndo = false;
wxString msg; wxString msg;
if( !m_processValues && !m_processFootprints && !m_processReferences && !m_processNetNames ) if( !m_processValues && !m_processFootprints && !m_processReferences && !m_processNetNames )
@ -79,9 +81,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
checkForUnusedSymbols(); checkForUnusedSymbols();
checkSharedSchematicErrors(); checkSharedSchematicErrors();
SCH_SHEET_PATH current = m_frame->GetCurrentSheet();
applyChangelist(); applyChangelist();
m_frame->SetCurrentSheet( current );
return true; return true;
} }
@ -280,12 +280,6 @@ bool BACK_ANNOTATE::checkReuseViolation( PCB_MODULE_DATA& aFirst, PCB_MODULE_DAT
return true; return true;
} }
wxString BACK_ANNOTATE::getTextFromField( const SCH_REFERENCE& aRef, const NumFieldType aField )
{
return aRef.GetComp()->GetField( aField )->GetText();
}
void BACK_ANNOTATE::checkSharedSchematicErrors() void BACK_ANNOTATE::checkSharedSchematicErrors()
{ {
std::sort( m_changelist.begin(), m_changelist.end(), 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. */ means that this particular component is reused in some other project. */
if( !m_ignoreOtherProjects && compUsage > usageCount ) if( !m_ignoreOtherProjects && compUsage > usageCount )
{ {
SCH_COMPONENT* comp = it->first.GetComp();
PCB_MODULE_DATA tmp{ "", PCB_MODULE_DATA tmp{ "",
getTextFromField( it->first, FOOTPRINT ), comp->GetField( FOOTPRINT )->GetText(),
getTextFromField( it->first, VALUE ), comp->GetField( VALUE )->GetText(),
{} }; {} };
if( !checkReuseViolation( tmp, *it->second ) ) if( !checkReuseViolation( tmp, *it->second ) )
@ -360,16 +355,16 @@ void BACK_ANNOTATE::applyChangelist()
{ {
std::set<wxString> handledNetChanges; std::set<wxString> handledNetChanges;
wxString msg; wxString msg;
int leftUnchanged = 0;
// Apply changes from change list // Apply changes from change list
for( CHANGELIST_ITEM& item : m_changelist ) for( CHANGELIST_ITEM& item : m_changelist )
{ {
SCH_REFERENCE& ref = item.first; SCH_REFERENCE& ref = item.first;
PCB_MODULE_DATA& module = *item.second; PCB_MODULE_DATA& module = *item.second;
wxString oldFootprint = getTextFromField( ref, FOOTPRINT ); SCH_COMPONENT* comp = ref.GetComp();
wxString oldValue = getTextFromField( ref, VALUE ); SCH_SCREEN* screen = ref.GetSheetPath().LastScreen();
int changesCountBefore = m_changesCount; wxString oldFootprint = comp->GetField( FOOTPRINT )->GetText();
wxString oldValue = comp->GetField( VALUE )->GetText();
bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0; bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0;
if( m_processReferences && ref.GetRef() != module.m_ref && !skip ) if( m_processReferences && ref.GetRef() != module.m_ref && !skip )
@ -380,7 +375,11 @@ void BACK_ANNOTATE::applyChangelist()
module.m_ref ); module.m_ref );
if( !m_dryRun ) 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 ); m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
} }
@ -390,11 +389,15 @@ void BACK_ANNOTATE::applyChangelist()
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ), msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ),
ref.GetFullRef(), ref.GetFullRef(),
getTextFromField( ref, FOOTPRINT ), comp->GetField( FOOTPRINT )->GetText(),
module.m_footprint ); module.m_footprint );
if( !m_dryRun ) if( !m_dryRun )
{
m_frame->SaveCopyInUndoList( screen, comp, UR_CHANGED, m_appendUndo );
m_appendUndo = true;
ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint ); ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint );
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
} }
@ -404,11 +407,15 @@ void BACK_ANNOTATE::applyChangelist()
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ), msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ),
ref.GetFullRef(), ref.GetFullRef(),
getTextFromField( ref, VALUE ), comp->GetField( VALUE )->GetText(),
module.m_value ); module.m_value );
if( !m_dryRun ) 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 ); m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
} }
@ -419,7 +426,6 @@ void BACK_ANNOTATE::applyChangelist()
{ {
const wxString& pinNumber = entry.first; const wxString& pinNumber = entry.first;
const wxString& shortNetName = entry.second; const wxString& shortNetName = entry.second;
SCH_COMPONENT* comp = ref.GetComp();
LIB_PIN* pin = comp->GetPin( pinNumber ); LIB_PIN* pin = comp->GetPin( pinNumber );
SCH_CONNECTION* conn = comp->GetConnectionForPin( pin, ref.GetSheetPath() ); SCH_CONNECTION* conn = comp->GetConnectionForPin( pin, ref.GetSheetPath() );
@ -434,11 +440,8 @@ void BACK_ANNOTATE::applyChangelist()
processNetNameChange( conn, conn->Name( true ), shortNetName ); 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 ); 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 ) 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<SCH_TEXT*>( label )->SetText( newName ); static_cast<SCH_TEXT*>( label )->SetText( newName );
} }
} }
@ -469,21 +473,20 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
{ {
case SCH_LABEL_T: case SCH_LABEL_T:
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change \"%s\" labels to \"%s\"." ), msg.Printf( _( "Change \"%s\" labels to \"%s\"." ), aOldName, aNewName );
aOldName,
aNewName );
if( !m_dryRun ) 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() ); SCH_CONNECTION* conn = label->Connection( aConn->Sheet() );
if( conn && conn->Driver() == driver ) 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<SCH_TEXT*>( label )->SetText( aNewName ); static_cast<SCH_TEXT*>( label )->SetText( aNewName );
} }
} }
@ -494,19 +497,12 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ), msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ), aOldName, aNewName );
aConn->Name( true ),
aNewName );
if( !m_dryRun ) if( !m_dryRun )
{ {
SCH_SHEET_LIST all_sheets = m_frame->Schematic().GetSheets(); for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().GetSheets() )
editMatchingLabels( sheet.LastScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName );
for( const SCH_SHEET_PATH& sheet : all_sheets )
{
m_frame->Schematic().SetCurrentSheet( sheet );
editMatchingLabels( m_frame->GetScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName );
}
} }
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); 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: case SCH_HIER_LABEL_T:
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), aOldName, aNewName );
aConn->Name( true ),
aNewName );
if( !m_dryRun ) if( !m_dryRun )
{ {
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); SCH_SCREEN* screen = aConn->Sheet().LastScreen();
editMatchingLabels( m_frame->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName ); editMatchingLabels( screen, SCH_HIER_LABEL_T, aOldName, aNewName );
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( driver->GetParent() ); SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( driver->GetParent() );
m_frame->SetScreen( sheet->GetScreen() ); screen = sheet->GetScreen();
for( SCH_SHEET_PIN* pin : sheet->GetPins() ) for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{ {
if( EscapeString( pin->GetShownText(), CTX_NETNAME ) == aOldName ) 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<SCH_TEXT*>( pin )->SetText( aNewName ); static_cast<SCH_TEXT*>( pin )->SetText( aNewName );
} }
} }
@ -541,19 +536,18 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
case SCH_SHEET_PIN_T: case SCH_SHEET_PIN_T:
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ), aOldName, aNewName );
aConn->Name( true ),
aNewName );
if( !m_dryRun ) if( !m_dryRun )
{ {
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); SCH_SCREEN* screen = aConn->Sheet().LastScreen();
m_frame->SaveCopyInUndoList( driver, UR_CHANGED ); m_frame->SaveCopyInUndoList( screen, driver, UR_CHANGED, m_appendUndo );
m_appendUndo = true;
static_cast<SCH_TEXT*>( driver )->SetText( aNewName ); static_cast<SCH_TEXT*>( driver )->SetText( aNewName );
SCH_SHEET* sheet = static_cast<SCH_SHEET_PIN*>( driver )->GetParent(); SCH_SHEET* sheet = static_cast<SCH_SHEET_PIN*>( driver )->GetParent();
m_frame->SetScreen( sheet->GetScreen() ); screen = sheet->GetScreen();
editMatchingLabels( sheet->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName ); editMatchingLabels( screen, SCH_HIER_LABEL_T, aOldName, aNewName );
} }
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
@ -584,9 +578,7 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
} }
++m_changesCount; ++m_changesCount;
msg.Printf( _( "Add label \"%s\" to net \"%s\"." ), msg.Printf( _( "Add label \"%s\" to net \"%s\"." ), aNewName, aOldName );
aNewName,
aConn->Name( true ) );
if( !m_dryRun ) if( !m_dryRun )
{ {
@ -598,8 +590,9 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
label->SetLabelSpinStyle( spin ); label->SetLabelSpinStyle( spin );
label->SetFlags( IS_NEW ); label->SetFlags( IS_NEW );
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() ); SCH_SCREEN* screen = aConn->Sheet().LastScreen();
m_frame->AddItemToScreenAndUndoList( label ); m_frame->AddItemToScreenAndUndoList( screen, label, m_appendUndo );
m_appendUndo = true;
} }
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
@ -609,6 +602,4 @@ void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString&
default: default:
break; break;
} }
m_frame->Schematic().SetCurrentSheet( SCH_SHEET_PATH() );
} }

View File

@ -115,11 +115,8 @@ private:
std::deque<CHANGELIST_ITEM> m_changelist; std::deque<CHANGELIST_ITEM> m_changelist;
SCH_EDIT_FRAME* m_frame; SCH_EDIT_FRAME* m_frame;
///> To count number of changes applied to the schematic int m_changesCount; // Number of user-level changes
int m_changesCount; bool m_appendUndo;
///> Get text from symbol's field ( such as Footprint or Value )
wxString getTextFromField( const SCH_REFERENCE& aRef, const NumFieldType aField );
/** /**
* @brief Check if modules has different data. Check only if corresponding \ref m_boardAdapter * @brief Check if modules has different data. Check only if corresponding \ref m_boardAdapter

View File

@ -137,10 +137,17 @@ protected:
wxASSERT( editFrame ); wxASSERT( editFrame );
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T ) if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
editFrame->SaveCopyInUndoList( {
static_cast<SCH_ITEM*>( aItem->GetParent() ), UR_CHANGED, aAppend ); editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
static_cast<SCH_ITEM*>( aItem->GetParent() ),
UR_CHANGED, aAppend );
}
else else
editFrame->SaveCopyInUndoList( static_cast<SCH_ITEM*>( aItem ), aType, aAppend ); {
editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
static_cast<SCH_ITEM*>( aItem ),
aType, aAppend );
}
} }
if( selected && aItem->HasFlag( TEMP_SELECTED ) ) if( selected && aItem->HasFlag( TEMP_SELECTED ) )

View File

@ -191,7 +191,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
SCH_COMPONENT* next_comp = nullptr; SCH_COMPONENT* next_comp = nullptr;
m_view->ClearPreview(); m_view->ClearPreview();
m_frame->AddItemToScreenAndUndoList( component ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), component, false );
EE_SELECTION new_sel; EE_SELECTION new_sel;
new_sel.Add( component ); new_sel.Add( component );
@ -388,7 +388,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
} }
else else
{ {
m_frame->AddItemToScreenAndUndoList( image ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), image, false );
image = nullptr; image = nullptr;
m_toolMgr->RunAction( ACTIONS::activatePointEditor ); 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( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) )
{ {
if( type == SCH_JUNCTION_T ) if( type == SCH_JUNCTION_T )
m_frame->AddJunction( cursorPos ); m_frame->AddJunction( m_frame->GetScreen(), cursorPos, false );
else else
{ {
SCH_ITEM* newItem = static_cast<SCH_ITEM*>( previewItem->Clone() ); SCH_ITEM* newItem = static_cast<SCH_ITEM*>( previewItem->Clone() );
newItem->SetPosition( cursorPos ); newItem->SetPosition( cursorPos );
newItem->SetFlags( IS_NEW ); newItem->SetFlags( IS_NEW );
m_frame->AddItemToScreenAndUndoList( newItem ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), newItem, false );
m_frame->SaveCopyForRepeatItem( newItem ); m_frame->SaveCopyForRepeatItem( newItem );
m_frame->SchematicCleanUp(); m_frame->SchematicCleanUp();
@ -855,7 +855,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
else else
{ {
item->ClearFlags( IS_MOVED ); item->ClearFlags( IS_MOVED );
m_frame->AddItemToScreenAndUndoList( (SCH_ITEM*) item ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, false );
item = getNextNewText(); item = getNextNewText();
if( item ) if( item )
@ -1007,7 +1007,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
{ {
sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
m_frame->AddItemToScreenAndUndoList( sheet ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), sheet, false );
m_frame->UpdateHierarchyNavigator(); m_frame->UpdateHierarchyNavigator();
m_selectionTool->AddItemToSel( sheet ); m_selectionTool->AddItemToSel( sheet );
} }

View File

@ -810,7 +810,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case SCH_HIER_LABEL_T: case SCH_HIER_LABEL_T:
case SCH_NO_CONNECT_T: case SCH_NO_CONNECT_T:
newItem->SetParent( m_frame->GetScreen() ); newItem->SetParent( m_frame->GetScreen() );
m_frame->AddToScreen( newItem ); m_frame->AddToScreen( newItem, m_frame->GetScreen() );
break; break;
case SCH_SHEET_T: case SCH_SHEET_T:
@ -828,7 +828,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
nameField.SetText( candidateName ); nameField.SetText( candidateName );
sheet->SetParent( m_frame->GetCurrentSheet().Last() ); sheet->SetParent( m_frame->GetCurrentSheet().Last() );
m_frame->AddToScreen( sheet ); m_frame->AddToScreen( sheet, m_frame->GetScreen() );
copiedSheets = true; copiedSheets = true;
break; break;
@ -839,7 +839,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
SCH_COMPONENT* component = (SCH_COMPONENT*) newItem; SCH_COMPONENT* component = (SCH_COMPONENT*) newItem;
component->ClearAnnotation( NULL ); component->ClearAnnotation( NULL );
component->SetParent( m_frame->GetScreen() ); component->SetParent( m_frame->GetScreen() );
m_frame->AddToScreen( component ); m_frame->AddToScreen( component, m_frame->GetScreen() );
break; break;
} }
@ -916,8 +916,8 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
} }
newItem->SetFlags( IS_NEW ); newItem->SetFlags( IS_NEW );
m_frame->AddToScreen( newItem ); m_frame->AddToScreen( newItem, m_frame->GetScreen() );
m_frame->SaveCopyInUndoList( newItem, UR_NEW ); m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UR_NEW, false );
m_selectionTool->AddItemToSel( newItem ); m_selectionTool->AddItemToSel( newItem );
@ -1011,7 +1011,9 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
sheet->RemovePin( pin ); sheet->RemovePin( pin );
} }
else else
m_frame->RemoveFromScreen( sch_item ); {
m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
}
if( sch_item->Type() == SCH_SHEET_T ) if( sch_item->Type() == SCH_SHEET_T )
m_frame->UpdateHierarchyNavigator(); 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. // Save old component in undo list if not already in edit, or moving.
if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved 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() ); 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(); SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front();
if( !component->IsNew() ) if( !component->IsNew() )
m_frame->SaveCopyInUndoList( component, UR_CHANGED ); saveCopyInUndoList( component, UR_CHANGED );
component->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true ); 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 ) int SCH_EDIT_TOOL::UpdateFields( const TOOL_EVENT& aEvent )
{ {
std::list<SCH_COMPONENT*> components; if( InvokeDialogUpdateFields( m_frame ) == wxID_OK )
for( auto item : m_frame->GetScreen()->Items().OfType( SCH_COMPONENT_T ) )
components.push_back( static_cast<SCH_COMPONENT*>( item ) );
if( InvokeDialogUpdateFields( m_frame, components, true ) == wxID_OK )
m_frame->GetCanvas()->Refresh(); m_frame->GetCanvas()->Refresh();
return 0; return 0;
@ -1245,7 +1242,7 @@ int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent )
return 0; return 0;
if( !component->IsNew() ) if( !component->IsNew() )
m_frame->SaveCopyInUndoList( component, UR_CHANGED ); saveCopyInUndoList( component, UR_CHANGED );
m_frame->ConvertPart( component ); m_frame->ConvertPart( component );
@ -1290,7 +1287,7 @@ int SCH_EDIT_TOOL::RefreshSymbolFromLibrary( const TOOL_EVENT& aEvent )
if( !symbol->IsNew() ) if( !symbol->IsNew() )
{ {
m_frame->SaveCopyInUndoList( symbol, UR_CHANGED, appendToUndo ); saveCopyInUndoList( symbol, UR_CHANGED, appendToUndo );
appendToUndo = true; 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 // save old image in undo list if not already in edit
if( bitmap->GetEditFlags() == 0 ) if( bitmap->GetEditFlags() == 0 )
m_frame->SaveCopyInUndoList( bitmap, UR_CHANGED ); saveCopyInUndoList( bitmap, UR_CHANGED );
dlg.TransferToImage( bitmap->GetImage() ); dlg.TransferToImage( bitmap->GetImage() );
@ -1613,11 +1610,11 @@ int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent )
if( !text->IsNew() ) if( !text->IsNew() )
{ {
m_frame->SaveCopyInUndoList( text, UR_DELETED ); saveCopyInUndoList( text, UR_DELETED );
m_frame->SaveCopyInUndoList( newtext, UR_NEW, true ); saveCopyInUndoList( newtext, UR_NEW, true );
m_frame->RemoveFromScreen( text ); m_frame->RemoveFromScreen( text, m_frame->GetScreen() );
m_frame->AddToScreen( newtext ); m_frame->AddToScreen( newtext, m_frame->GetScreen() );
} }
if( selected ) if( selected )
@ -1656,7 +1653,7 @@ int SCH_EDIT_TOOL::BreakWire( const TOOL_EVENT& aEvent )
if( m_frame->BreakSegments( cursorPos ) ) if( m_frame->BreakSegments( cursorPos ) )
{ {
if( m_frame->GetScreen()->IsJunctionNeeded( cursorPos, true ) ) 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(); 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?" ) ) ) if( !IsOK( m_frame, _( "Do you wish to delete the unreferenced pins from this sheet?" ) ) )
return 0; return 0;
m_frame->SaveCopyInUndoList( sheet, UR_CHANGED ); saveCopyInUndoList( sheet, UR_CHANGED );
sheet->CleanupSheet(); sheet->CleanupSheet();

View File

@ -100,10 +100,10 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent )
{ {
PICKED_ITEMS_LIST undoCmd; PICKED_ITEMS_LIST undoCmd;
WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( m_frame ); 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 ); 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 ) ); DIALOG_PAGES_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
dlg.SetWksFileName( BASE_SCREEN::m_PageLayoutDescrFileName ); 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->RecalculateConnections( GLOBAL_CLEANUP );
} }
m_frame->GetScreen()->ClearUndoORRedoList( m_frame->GetScreen()->m_UndoList, 1 ); m_frame->ClearUndoRedoList();
m_frame->SyncView(); m_frame->SyncView();
m_frame->GetCanvas()->Refresh(); m_frame->GetCanvas()->Refresh();
m_frame->OnModify(); 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 ) int SCH_EDITOR_CONTROL::Undo( const TOOL_EVENT& aEvent )
{ {
if( m_frame->GetScreen()->GetUndoCommandCount() <= 0 ) if( m_frame->GetUndoCommandCount() <= 0 )
return 0; return 0;
// Inform tools that undo command was issued // Inform tools that undo command was issued
m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = m_frame->GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* List = m_frame->PopCommandFromUndoList();
/* Undo the command */ /* Undo the command */
m_frame->PutDataInPreviousState( List, false ); m_frame->PutDataInPreviousState( List, false );
/* Put the old list in RedoList */ /* Put the old list in RedoList */
List->ReversePickersListOrder(); List->ReversePickersListOrder();
m_frame->GetScreen()->PushCommandToRedoList( List ); m_frame->PushCommandToRedoList( List );
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>(); EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
selTool->RebuildSelection(); selTool->RebuildSelection();
@ -1192,21 +1192,21 @@ int SCH_EDITOR_CONTROL::Undo( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Redo( 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; return 0;
// Inform tools that undo command was issued // Inform tools that undo command was issued
m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); m_toolMgr->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = m_frame->GetScreen()->PopCommandFromRedoList(); PICKED_ITEMS_LIST* List = m_frame->PopCommandFromRedoList();
/* Redo the command: */ /* Redo the command: */
m_frame->PutDataInPreviousState( List, true ); m_frame->PutDataInPreviousState( List, true );
/* Put the old list in UndoList */ /* Put the old list in UndoList */
List->ReversePickersListOrder(); List->ReversePickersListOrder();
m_frame->GetScreen()->PushCommandToUndoList( List ); m_frame->PushCommandToUndoList( List );
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>(); EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
selTool->RebuildSelection(); selTool->RebuildSelection();
@ -1495,7 +1495,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
} }
item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED ); 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 // Reset flags for subsequent move operation
item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED ); item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED );

View File

@ -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 = new SCH_BUS_WIRE_ENTRY( pos );
m_busUnfold.entry->SetParent( m_frame->GetScreen() ); 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 = new SCH_LABEL( m_busUnfold.entry->m_End(), aNet );
m_busUnfold.label->SetTextSize( wxSize( cfg.m_DefaultTextSize, cfg.m_DefaultTextSize ) ); 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; segment = nullptr;
if( m_busUnfold.entry ) 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 ) if( m_busUnfold.label && !m_busUnfold.label_placed )
m_selectionTool->RemoveItemFromSel( m_busUnfold.label, true ); m_selectionTool->RemoveItemFromSel( m_busUnfold.label, true );
if( m_busUnfold.label && m_busUnfold.label_placed ) 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.entry;
delete m_busUnfold.label; 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 ); 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_selectionTool->RemoveItemFromSel( m_busUnfold.label, true );
m_busUnfold.label_placed = true; m_busUnfold.label_placed = true;
} }
@ -808,6 +808,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
// freed selected items. // freed selected items.
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
SCH_SCREEN* screen = m_frame->GetScreen();
PICKED_ITEMS_LIST itemList; PICKED_ITEMS_LIST itemList;
// Remove segments backtracking over others // Remove segments backtracking over others
@ -831,15 +832,15 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), i ) ) if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), i ) )
new_ends.push_back( 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 ) if( m_busUnfold.in_progress && m_busUnfold.label_placed )
{ {
wxASSERT( m_busUnfold.entry && m_busUnfold.label ); wxASSERT( m_busUnfold.entry && m_busUnfold.label );
itemList.PushItem( ITEM_PICKER( m_busUnfold.entry, UR_NEW ) ); itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.entry, UR_NEW ) );
itemList.PushItem( ITEM_PICKER( m_busUnfold.label, UR_NEW ) ); itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.label, UR_NEW ) );
m_busUnfold.label->ClearEditFlags(); m_busUnfold.label->ClearEditFlags();
} }
@ -851,7 +852,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
for( auto wire : m_wires ) for( auto wire : m_wires )
{ {
wire->ClearFlags( IS_NEW | IS_MOVED ); wire->ClearFlags( IS_NEW | IS_MOVED );
m_frame->AddToScreen( wire ); m_frame->AddToScreen( wire, screen );
} }
m_wires.clear(); m_wires.clear();
@ -861,7 +862,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
getViewControls()->CaptureCursor( false ); getViewControls()->CaptureCursor( false );
getViewControls()->SetAutoPan( 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. // Correct and remove segments that need to be merged.
m_frame->SchematicCleanUp(); m_frame->SchematicCleanUp();
@ -884,7 +885,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
for( auto i : new_ends ) for( auto i : new_ends )
{ {
if( m_frame->GetScreen()->IsJunctionNeeded( i, true ) ) 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 ) if( m_busUnfold.in_progress )
@ -949,7 +950,7 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent )
for( auto point : pts ) for( auto point : pts )
{ {
if( m_frame->GetScreen()->IsJunctionNeeded( point, true ) ) if( m_frame->GetScreen()->IsJunctionNeeded( point, true ) )
m_frame->AddJunction( point, true, false ); m_frame->AddJunction( m_frame->GetScreen(), point, true, false );
} }
return 0; return 0;

View File

@ -470,7 +470,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
for( auto it : internalPoints ) for( auto it : internalPoints )
{ {
if( m_frame->GetScreen()->IsJunctionNeeded( it.GetPosition(), true ) ) 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 ); m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection );

View File

@ -33,7 +33,6 @@
#include <eda_draw_frame.h> #include <eda_draw_frame.h>
#include <base_struct.h> #include <base_struct.h>
#include <undo_redo_container.h>
#include <common.h> #include <common.h>
@ -46,7 +45,6 @@ class BASE_SCREEN : public EDA_ITEM
private: private:
bool m_FlagModified; ///< Indicates current drawing has been modified. bool m_FlagModified; ///< Indicates current drawing has been modified.
bool m_FlagSave; ///< Indicates automatic file save. 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 * The cross hair position in logical (drawing) units. The cross hair is not the cursor
@ -78,12 +76,8 @@ public:
bool m_Initialized; bool m_Initialized;
// Undo/redo list of commands int m_ScreenNumber;
UNDO_REDO_CONTAINER m_UndoList; ///< Objects list for the undo command (old data) int m_NumberOfScreens;
UNDO_REDO_CONTAINER m_RedoList; ///< Objects list for the redo command (old data)
int m_ScreenNumber;
int m_NumberOfScreens;
public: public:
BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType = SCREEN_T ); BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType = SCREEN_T );
@ -102,83 +96,6 @@ public:
void InitDataPoints( const wxSize& aPageSizeInternalUnits ); 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 SetModify() { m_FlagModified = true; }
void ClrModify() { m_FlagModified = false; } void ClrModify() { m_FlagModified = false; }

View File

@ -48,6 +48,7 @@
#include <kiway_holder.h> #include <kiway_holder.h>
#include <tool/tools_holder.h> #include <tool/tools_holder.h>
#include <widgets/ui_common.h> #include <widgets/ui_common.h>
#include <undo_redo_container.h>
// Option for main frames // Option for main frames
#define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS #define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS
@ -85,6 +86,9 @@ enum id_librarytype {
LIBRARY_TYPE_SYMBOL LIBRARY_TYPE_SYMBOL
}; };
#define DEFAULT_MAX_UNDO_ITEMS 0
#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2)
wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent ); wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent );
@ -137,13 +141,23 @@ protected:
SETTINGS_MANAGER* m_settingsManager; 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_hasAutoSave;
bool m_autoSaveState; bool m_autoSaveState;
int m_autoSaveInterval; // The auto save interval time in seconds. int m_autoSaveInterval; // The auto save interval time in seconds.
wxTimer* m_autoSaveTimer; 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. wxString m_mruPath; // Most recently used path.
EDA_UNITS m_userUnits; EDA_UNITS m_userUnits;
@ -521,6 +535,85 @@ public:
* @return the undecorated window size * @return the undecorated window size
*/ */
wxSize GetWindowSize(); 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;
}
}
}; };

View File

@ -50,8 +50,6 @@ namespace KIGFX
using KIGFX::COLOR4D; using KIGFX::COLOR4D;
using KIGFX::RENDER_SETTINGS; 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 LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" ) #define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
#define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" ) #define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" )

View File

@ -22,10 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file pcb_screen.h
*/
#ifndef PCB_SCREEN_H #ifndef PCB_SCREEN_H
#define PCB_SCREEN_H #define PCB_SCREEN_H
@ -34,9 +30,6 @@
#include <class_board_item.h> #include <class_board_item.h>
class UNDO_REDO_CONTAINER;
/* Handle info to display a board */ /* Handle info to display a board */
class PCB_SCREEN : public BASE_SCREEN class PCB_SCREEN : public BASE_SCREEN
{ {
@ -46,35 +39,11 @@ public:
PCB_LAYER_ID m_Route_Layer_BOTTOM; PCB_LAYER_ID m_Route_Layer_BOTTOM;
public: public:
/** /**
* Constructor * Constructor
* @param aPageSizeIU is the size of the initial paper page in internal units. * @param aPageSizeIU is the size of the initial paper page in internal units.
*/ */
PCB_SCREEN( const wxSize& aPageSizeIU ); 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 #endif // PCB_SCREEN_H

View File

@ -31,6 +31,7 @@
class PICKED_ITEMS_LIST; class PICKED_ITEMS_LIST;
class BASE_SCREEN;
/** /**
@ -90,8 +91,13 @@ private:
* copy of an active item) and m_Link points the active * copy of an active item) and m_Link points the active
* item in schematic */ * item in schematic */
BASE_SCREEN* m_screen; /* For new and deleted items the screen the item should
* be added to/removed from. */
public: 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; } EDA_ITEM* GetItem() const { return m_pickedItem; }
@ -114,6 +120,8 @@ public:
void SetLink( EDA_ITEM* aItem ) { m_link = aItem; } void SetLink( EDA_ITEM* aItem ) { m_link = aItem; }
EDA_ITEM* GetLink() const { return m_link; } EDA_ITEM* GetLink() const { return m_link; }
BASE_SCREEN* GetScreen() const { return m_screen; }
}; };
@ -125,10 +133,10 @@ public:
class PICKED_ITEMS_LIST class PICKED_ITEMS_LIST
{ {
public: public:
UNDO_REDO_T m_Status; /* info about operation to undo/redo for this item. can be UNDO_REDO_T m_Status; /* info about operation to undo/redo for this item. can be
* UR_UNSPECIFIED */ * UR_UNSPECIFIED */
wxPoint m_TransformPoint; /* used to undo redo command by the same command: usually wxPoint m_TransformPoint; /* used to undo redo command by the same command: usually
* need to know the rotate point or the move vector */ * need to know the rotate point or the move vector */
private: private:
std::vector <ITEM_PICKER> m_ItemsList; std::vector <ITEM_PICKER> m_ItemsList;
@ -211,6 +219,13 @@ public:
*/ */
EDA_ITEM* GetPickedItem( unsigned int aIdx ) const; 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 * Function GetPickedItemLink
* @return link of the picked item, or null if does not exist * @return link of the picked item, or null if does not exist

View File

@ -22,7 +22,6 @@ set( PL_EDITOR_SRCS
dialogs/panel_pl_editor_color_settings.cpp dialogs/panel_pl_editor_color_settings.cpp
dialogs/panel_pl_editor_color_settings_base.cpp dialogs/panel_pl_editor_color_settings_base.cpp
design_inspector.cpp design_inspector.cpp
pl_editor_screen.cpp
pl_editor_layout.cpp pl_editor_layout.cpp
files.cpp files.cpp
pl_editor_frame.cpp pl_editor_frame.cpp

View File

@ -152,7 +152,7 @@ void PLEDITOR_PRINTOUT::PrintPage( int aPageNum )
wxPoint old_org; wxPoint old_org;
wxRect fitRect; wxRect fitRect;
wxDC* dc = GetDC(); wxDC* dc = GetDC();
PL_EDITOR_SCREEN* screen = m_parent->GetScreen(); BASE_SCREEN* screen = m_parent->GetScreen();
// Save current offsets and clip box. // Save current offsets and clip box.
tmp_startvisu = screen->m_StartVisu; tmp_startvisu = screen->m_StartVisu;

View File

@ -90,10 +90,10 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetUndoCommandCount() != 0; return GetUndoCommandCount() != 0;
}; };
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetRedoCommandCount() != 0; return GetRedoCommandCount() != 0;
}; };
auto idleCondition = [] ( const SELECTION& sel ) { auto idleCondition = [] ( const SELECTION& sel ) {
return !sel.Front() || sel.Front()->GetEditFlags() == 0; return !sel.Front() || sel.Front()->GetEditFlags() == 0;

View File

@ -34,7 +34,6 @@
#include <pl_editor_id.h> #include <pl_editor_id.h>
#include <pl_editor_settings.h> #include <pl_editor_settings.h>
#include <pl_draw_panel_gal.h> #include <pl_draw_panel_gal.h>
#include <pl_editor_screen.h>
#include <ws_data_model.h> #include <ws_data_model.h>
#include <properties_frame.h> #include <properties_frame.h>
#include <widgets/paged_dialog.h> #include <widgets/paged_dialog.h>
@ -114,7 +113,7 @@ PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
LoadSettings( config() ); LoadSettings( config() );
wxSize pageSizeIU = GetPageLayout().GetPageSettings().GetSizeIU(); wxSize pageSizeIU = GetPageLayout().GetPageSettings().GetSizeIU();
SetScreen( new PL_EDITOR_SCREEN( pageSizeIU ) ); SetScreen( new BASE_SCREEN( pageSizeIU ) );
setupTools(); setupTools();
ReCreateMenuBar(); ReCreateMenuBar();
@ -612,11 +611,6 @@ void PL_EDITOR_FRAME::DisplayGridMsg()
void PL_EDITOR_FRAME::UpdateStatusBar() void PL_EDITOR_FRAME::UpdateStatusBar()
{ {
PL_EDITOR_SCREEN* screen = (PL_EDITOR_SCREEN*) GetScreen();
if( !screen )
return;
// Display Zoom level: // Display Zoom level:
EDA_DRAW_FRAME::UpdateStatusBar(); EDA_DRAW_FRAME::UpdateStatusBar();
@ -663,16 +657,10 @@ void PL_EDITOR_FRAME::UpdateStatusBar()
switch( GetUserUnits() ) switch( GetUserUnits() )
{ {
case EDA_UNITS::INCHES: case EDA_UNITS::INCHES: SetStatusText( _( "inches" ), 6 ); break;
SetStatusText( _( "inches" ), 6 ); case EDA_UNITS::MILLIMETRES: SetStatusText( _( "mm" ), 6 ); break;
break; case EDA_UNITS::UNSCALED: SetStatusText( wxEmptyString, 6 ); break;
case EDA_UNITS::MILLIMETRES: default: wxASSERT( false ); break;
SetStatusText( _( "mm" ), 6 );
break;
case EDA_UNITS::UNSCALED:
SetStatusText( wxEmptyString, 6 );
break;
default: wxASSERT( false ); break;
} }
wxString line; wxString line;
@ -689,12 +677,15 @@ void PL_EDITOR_FRAME::UpdateStatusBar()
SetStatusText( line, 2 ); SetStatusText( line, 2 );
// Display relative coordinates: // Display relative coordinates:
double dx = cursorPos.x - screen->m_LocalOrigin.x; if( GetScreen() )
double dy = cursorPos.y - screen->m_LocalOrigin.y; {
dXpos = To_User_Unit( GetUserUnits(), dx * Xsign ); double dx = cursorPos.x - GetScreen()->m_LocalOrigin.x;
dYpos = To_User_Unit( GetUserUnits(), dy * Ysign ); double dy = cursorPos.y - GetScreen()->m_LocalOrigin.y;
line.Printf( locformatter, dXpos, dYpos ); dXpos = To_User_Unit( GetUserUnits(), dx * Xsign );
SetStatusText( line, 3 ); dYpos = To_User_Unit( GetUserUnits(), dy * Ysign );
line.Printf( locformatter, dXpos, dYpos );
SetStatusText( line, 3 );
}
DisplayGridMsg(); DisplayGridMsg();
@ -819,7 +810,7 @@ WS_DATA_ITEM* PL_EDITOR_FRAME::AddPageLayoutItem( int aType )
void PL_EDITOR_FRAME::OnNewPageLayout() void PL_EDITOR_FRAME::OnNewPageLayout()
{ {
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
GetScreen()->ClrModify(); GetScreen()->ClrModify();
GetCanvas()->DisplayWorksheet(); 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
}
}

View File

@ -29,7 +29,7 @@
#include <config_params.h> #include <config_params.h>
#include <eda_draw_frame.h> #include <eda_draw_frame.h>
#include <pl_editor_screen.h> #include <base_screen.h>
#include <pl_editor_layout.h> #include <pl_editor_layout.h>
#include <pl_draw_panel_gal.h> #include <pl_draw_panel_gal.h>
@ -124,11 +124,6 @@ public:
PL_DRAW_PANEL_GAL* GetCanvas() const override; 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; } const wxPoint& GetGridOrigin() const override { return m_grid_origin; }
void SetGridOrigin( const wxPoint& aPoint ) override { m_grid_origin = aPoint; } 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. * 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: /** Redo the last edit:
* - Place the current edited layout in undo list * - Place the current edited layout in undo list
@ -288,6 +282,11 @@ public:
*/ */
void RollbackFromUndo(); void RollbackFromUndo();
/**
* Function ClearUndoORRedoList
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
protected: protected:
bool saveCurrentPageLayout(); bool saveCurrentPageLayout();

View File

@ -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 <fctsys.h>
#include <pl_editor_screen.h>
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
}
}

View File

@ -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 <base_screen.h>
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_

View File

@ -24,27 +24,25 @@
*/ */
#include <fctsys.h> #include <fctsys.h>
#include <macros.h>
#include <ws_data_model.h> #include <ws_data_model.h>
#include <ws_draw_item.h>
#include <pl_editor_frame.h> #include <pl_editor_frame.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/pl_selection_tool.h> #include <tools/pl_selection_tool.h>
#include <ws_proxy_undo_item.h> #include <ws_proxy_undo_item.h>
#include <tool/actions.h> #include <tool/actions.h>
void PL_EDITOR_FRAME::SaveCopyInUndoList( bool aSavePageSettingsAndTitleBlock )
void PL_EDITOR_FRAME::SaveCopyInUndoList()
{ {
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
WS_PROXY_UNDO_ITEM* copyItem = new WS_PROXY_UNDO_ITEM( this ); 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 ); lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd ); PushCommandToUndoList( lastcmd );
// Clear redo list, because after new save there is no redo to do. // 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<PL_SELECTION_TOOL>(); PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetRedoCommandCount() <= 0 ) if ( GetRedoCommandCount() <= 0 )
return; return;
ITEM_PICKER redoWrapper = GetScreen()->PopCommandFromRedoList()->PopItem(); ITEM_PICKER redoWrapper = PopCommandFromRedoList()->PopItem();
WS_PROXY_UNDO_ITEM* redoItem = static_cast<WS_PROXY_UNDO_ITEM*>( redoWrapper.GetItem() ); WS_PROXY_UNDO_ITEM* redoItem = static_cast<WS_PROXY_UNDO_ITEM*>( redoWrapper.GetItem() );
bool pageSettingsAndTitleBlock = redoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; bool pageSettingsAndTitleBlock = redoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
PICKED_ITEMS_LIST* undoCmd = new PICKED_ITEMS_LIST(); 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 ) ); undoCmd->PushItem( undoWrapper );
GetScreen()->PushCommandToUndoList( undoCmd ); PushCommandToUndoList( undoCmd );
selTool->ClearSelection(); selTool->ClearSelection();
redoItem->Restore( this, GetCanvas()->GetView() ); redoItem->Restore( this, GetCanvas()->GetView() );
@ -91,17 +91,19 @@ void PL_EDITOR_FRAME::GetLayoutFromUndoList()
{ {
PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>(); PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetUndoCommandCount() <= 0 ) if ( GetUndoCommandCount() <= 0 )
return; return;
ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem(); ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem();
WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() ); WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
PICKED_ITEMS_LIST* redoCmd = new PICKED_ITEMS_LIST(); 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 ) ); redoCmd->PushItem( redoWrapper );
GetScreen()->PushCommandToRedoList( redoCmd ); PushCommandToRedoList( redoCmd );
selTool->ClearSelection(); selTool->ClearSelection();
undoItem->Restore( this, GetCanvas()->GetView() ); undoItem->Restore( this, GetCanvas()->GetView() );
@ -125,10 +127,10 @@ void PL_EDITOR_FRAME::RollbackFromUndo()
{ {
PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>(); PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetUndoCommandCount() <= 0 ) if ( GetUndoCommandCount() <= 0 )
return; return;
ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem(); ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem();
WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() ); WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T; bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;

View File

@ -151,8 +151,8 @@ void PL_EDITOR_FRAME::SyncToolbars()
#define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) ) #define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) )
m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );
m_mainToolBar->Refresh(); m_mainToolBar->Refresh();

View File

@ -85,7 +85,7 @@ int PL_EDITOR_CONTROL::SaveAs( const TOOL_EVENT& aEvent )
int PL_EDITOR_CONTROL::PageSetup( 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 ) ); DIALOG_PAGES_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
dlg.SetWksFileName( m_frame->GetCurrentFileName() ); dlg.SetWksFileName( m_frame->GetCurrentFileName() );

View File

@ -123,7 +123,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
if( aCreateUndoEntry ) if( aCreateUndoEntry )
{ {
ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED ); ITEM_PICKER itemWrapper( nullptr, ent.m_item, UR_CHANGED );
itemWrapper.SetLink( ent.m_copy ); itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );
frame->SaveCopyInUndoList( undoList, UR_CHANGED ); frame->SaveCopyInUndoList( undoList, UR_CHANGED );
@ -158,7 +158,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
else else
{ {
if( aCreateUndoEntry ) if( aCreateUndoEntry )
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) ); undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UR_NEW ) );
if( !( changeFlags & CHT_DONE ) ) if( !( changeFlags & CHT_DONE ) )
board->Add( boardItem ); // handles connectivity board->Add( boardItem ); // handles connectivity
@ -171,7 +171,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
case CHT_REMOVE: case CHT_REMOVE:
{ {
if( !m_editModules && aCreateUndoEntry ) if( !m_editModules && aCreateUndoEntry )
undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) ); undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UR_DELETED ) );
if( boardItem->IsSelected() ) if( boardItem->IsSelected() )
{ {
@ -252,7 +252,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
{ {
if( !m_editModules && aCreateUndoEntry ) if( !m_editModules && aCreateUndoEntry )
{ {
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); ITEM_PICKER itemWrapper( nullptr, boardItem, UR_CHANGED );
wxASSERT( ent.m_copy ); wxASSERT( ent.m_copy );
itemWrapper.SetLink( ent.m_copy ); itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );
@ -299,7 +299,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
if( aCreateUndoEntry ) if( aCreateUndoEntry )
{ {
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); ITEM_PICKER itemWrapper( nullptr, boardItem, UR_CHANGED );
wxASSERT( ent.m_copy ); wxASSERT( ent.m_copy );
itemWrapper.SetLink( ent.m_copy ); itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper ); undoList.PushItem( itemWrapper );

View File

@ -1703,7 +1703,7 @@ ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
if( aNewZonesList ) if( aNewZonesList )
{ {
ITEM_PICKER picker( new_area, UR_NEW ); ITEM_PICKER picker( nullptr, new_area, UR_NEW );
aNewZonesList->PushItem( picker ); aNewZonesList->PushItem( picker );
} }
@ -1718,7 +1718,7 @@ void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to
if( aDeletedList ) if( aDeletedList )
{ {
ITEM_PICKER picker( area_to_remove, UR_DELETED ); ITEM_PICKER picker( nullptr, area_to_remove, UR_DELETED );
aDeletedList->PushItem( picker ); aDeletedList->PushItem( picker );
Remove( area_to_remove ); // remove from zone list, but does not delete it Remove( area_to_remove ); // remove from zone list, but does not delete it
} }

View File

@ -305,7 +305,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::processItem( PICKED_ITEMS_LIST* aUndoLi
{ {
if( aUndoList->FindItem( aItem ) < 0 ) if( aUndoList->FindItem( aItem ) < 0 )
{ {
ITEM_PICKER picker( aItem, UR_CHANGED ); ITEM_PICKER picker( nullptr, aItem, UR_CHANGED );
picker.SetLink( aItem->Clone() ); picker.SetLink( aItem->Clone() );
aUndoList->PushItem( picker ); aUndoList->PushItem( picker );
} }

View File

@ -104,7 +104,7 @@ int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
if( aItemsListPicker ) if( aItemsListPicker )
{ {
aTrackItem->SetWidth( initial_width ); aTrackItem->SetWidth( initial_width );
ITEM_PICKER picker( aTrackItem, UR_CHANGED ); ITEM_PICKER picker( nullptr, aTrackItem, UR_CHANGED );
picker.SetLink( aTrackItem->Clone() ); picker.SetLink( aTrackItem->Clone() );
aItemsListPicker->PushItem( picker ); aItemsListPicker->PushItem( picker );
aTrackItem->SetWidth( new_width ); aTrackItem->SetWidth( new_width );

View File

@ -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 // In modedit, set the default paper size to A4 for plot/print
SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) ); SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) );
SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
// Create the manager and dispatcher & route draw panel events to the dispatcher // Create the manager and dispatcher & route draw panel events to the dispatcher
setupTools(); setupTools();

View File

@ -985,7 +985,7 @@ bool FOOTPRINT_EDIT_FRAME::RevertFootprint()
Update3DView( true ); Update3DView( true );
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
GetScreen()->ClrModify(); GetScreen()->ClrModify();
updateView(); updateView();

View File

@ -55,7 +55,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal )
ReleaseFile(); ReleaseFile();
// Clear undo and redo lists because we want a full deletion // Clear undo and redo lists because we want a full deletion
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
GetScreen()->ClrModify(); GetScreen()->ClrModify();
if( !aFinal ) 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 // Clear undo and redo lists because we want a full deletion
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
GetScreen()->ClrModify(); GetScreen()->ClrModify();
BOARD* board = new BOARD; BOARD* board = new BOARD;

View File

@ -139,7 +139,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
m_adapter->SetPreselectNode( newModule->GetFPID(), 0 ); m_adapter->SetPreselectNode( newModule->GetFPID(), 0 );
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
GetScreen()->ClrModify(); GetScreen()->ClrModify();
// Update the save items if needed. // Update the save items if needed.
@ -482,7 +482,7 @@ void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, bool aRecreateRatsnest )
} }
else if( aModule->IsMoving() ) else if( aModule->IsMoving() )
{ {
ITEM_PICKER picker( aModule, UR_CHANGED ); ITEM_PICKER picker( nullptr, aModule, UR_CHANGED );
picker.SetLink( s_ModuleInitialCopy ); picker.SetLink( s_ModuleInitialCopy );
s_PickedList.PushItem( picker ); s_PickedList.PushItem( picker );
s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy. s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy.

View File

@ -111,10 +111,10 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; return GetUndoCommandCount() > 0;
}; };
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; return GetRedoCommandCount() > 0;
}; };
auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) {
return ToolStackIsEmpty(); return ToolStackIsEmpty();

View File

@ -210,10 +210,10 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool ); CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) { auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetUndoCommandCount() > 0; return GetUndoCommandCount() > 0;
}; };
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) { auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->GetRedoCommandCount() > 0; return GetRedoCommandCount() > 0;
}; };
auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) {
return ToolStackIsEmpty(); return ToolStackIsEmpty();

View File

@ -24,13 +24,10 @@
#include <pcb_base_edit_frame.h> #include <pcb_base_edit_frame.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <pcb_draw_panel_gal.h>
#include <pcb_layer_widget.h> #include <pcb_layer_widget.h>
#include <pcbnew_settings.h> #include <pcbnew_settings.h>
#include <pgm_base.h> #include <pgm_base.h>
#include <gal/graphics_abstraction_layer.h>
#include <class_board.h> #include <class_board.h>
#include <view/view.h>
#include "footprint_info_impl.h" #include "footprint_info_impl.h"
#include <project.h> #include <project.h>
#include <settings/color_settings.h> #include <settings/color_settings.h>
@ -139,3 +136,5 @@ COLOR_SETTINGS* PCB_BASE_EDIT_FRAME::GetColorSettings()
{ {
return Pgm().GetSettingsManager().GetColorSettings( GetPcbNewSettings()->m_ColorTheme ); return Pgm().GetSettingsManager().GetColorSettings( GetPcbNewSettings()->m_ColorTheme );
} }

View File

@ -185,6 +185,26 @@ public:
COLOR_SETTINGS* GetColorSettings() override; 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: protected:
/// User defined rotation angle (in tenths of a degree). /// User defined rotation angle (in tenths of a degree).
int m_rotationAngle; int m_rotationAngle;

View File

@ -206,7 +206,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
LoadSettings( config() ); LoadSettings( config() );
SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
// PCB drawings start in the upper left corner. // PCB drawings start in the upper left corner.
GetScreen()->m_Center = false; GetScreen()->m_Center = false;

View File

@ -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_TOP = F_Cu; // default layers pair for vias (bottom to top)
m_Route_Layer_BOTTOM = B_Cu; m_Route_Layer_BOTTOM = B_Cu;
} }
PCB_SCREEN::~PCB_SCREEN()
{
ClearUndoRedoList();
}

View File

@ -56,7 +56,7 @@ bool PCB_EDIT_FRAME::ImportSpecctraSession( const wxString& fullFileName )
// To avoid issues with undo/redo lists (dangling pointers) // To avoid issues with undo/redo lists (dangling pointers)
// clear the lists // clear the lists
// todo: use undo/redo feature // todo: use undo/redo feature
GetScreen()->ClearUndoRedoList(); ClearUndoRedoList();
SPECCTRA_DB db; SPECCTRA_DB db;
LOCALE_IO toggle; LOCALE_IO toggle;

View File

@ -222,29 +222,28 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
// Append tracks: // Append tracks:
for( auto item : currentPcb->Tracks() ) for( auto item : currentPcb->Tracks() )
{ {
ITEM_PICKER picker( item, UR_CHANGED ); ITEM_PICKER picker( nullptr, item, UR_CHANGED );
itemsList.PushItem( picker ); itemsList.PushItem( picker );
} }
// Append modules: // Append modules:
for( auto item : currentPcb->Modules() ) for( auto item : currentPcb->Modules() )
{ {
ITEM_PICKER picker( item, UR_CHANGED ); ITEM_PICKER picker( nullptr, item, UR_CHANGED );
itemsList.PushItem( picker ); itemsList.PushItem( picker );
} }
// Append drawings // Append drawings
for( auto item : currentPcb->Drawings() ) for( auto item : currentPcb->Drawings() )
{ {
ITEM_PICKER picker( item, UR_CHANGED ); ITEM_PICKER picker( nullptr, item, UR_CHANGED );
itemsList.PushItem( picker ); itemsList.PushItem( picker );
} }
// Append zones outlines // Append zones outlines
for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ ) for( int ii = 0; ii < currentPcb->GetAreaCount(); ii++ )
{ {
ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( ITEM_PICKER picker( nullptr, (EDA_ITEM*) currentPcb->GetArea( ii ), UR_CHANGED );
ii ), UR_CHANGED );
itemsList.PushItem( picker ); itemsList.PushItem( picker );
} }
@ -270,7 +269,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
} }
else else
{ {
oldBuffer = GetScreen()->PopCommandFromUndoList(); oldBuffer = PopCommandFromUndoList();
wxASSERT( oldBuffer ); wxASSERT( oldBuffer );
} }
@ -280,15 +279,15 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
// The list of existing items after running the action script // The list of existing items after running the action script
std::set<BOARD_ITEM*> currItemList; std::set<BOARD_ITEM*> currItemList;
// Append tracks: // Append tracks:
for( auto item : currentPcb->Tracks() ) for( TRACK* item : currentPcb->Tracks() )
currItemList.insert( item ); currItemList.insert( item );
// Append modules: // Append modules:
for( auto item : currentPcb->Modules() ) for( MODULE* item : currentPcb->Modules() )
currItemList.insert( item ); currItemList.insert( item );
// Append drawings // Append drawings
for( auto item : currentPcb->Drawings() ) for( BOARD_ITEM* item : currentPcb->Drawings() )
currItemList.insert( item ); currItemList.insert( item );
// Append zones outlines // Append zones outlines
@ -299,7 +298,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
for( unsigned int i = 0; i < oldBuffer->GetCount(); i++ ) for( unsigned int i = 0; i < oldBuffer->GetCount(); i++ )
{ {
BOARD_ITEM* item = (BOARD_ITEM*) oldBuffer->GetPickedItem( i ); BOARD_ITEM* item = (BOARD_ITEM*) oldBuffer->GetPickedItem( i );
ITEM_PICKER picker( item, UR_DELETED ); ITEM_PICKER picker( nullptr, item, UR_DELETED );
wxASSERT( item ); wxASSERT( item );
@ -314,29 +313,29 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
} }
// Find new modules // Find new modules
for( auto item : currentPcb->Modules() ) for( MODULE* item : currentPcb->Modules() )
{ {
if( !oldBuffer->ContainsItem( item ) ) if( !oldBuffer->ContainsItem( item ) )
{ {
ITEM_PICKER picker( item, UR_NEW ); ITEM_PICKER picker( nullptr, item, UR_NEW );
oldBuffer->PushItem( picker ); oldBuffer->PushItem( picker );
} }
} }
for( auto item : currentPcb->Tracks() ) for( TRACK* item : currentPcb->Tracks() )
{ {
if( !oldBuffer->ContainsItem( item ) ) if( !oldBuffer->ContainsItem( item ) )
{ {
ITEM_PICKER picker( item, UR_NEW ); ITEM_PICKER picker( nullptr, item, UR_NEW );
oldBuffer->PushItem( picker ); oldBuffer->PushItem( picker );
} }
} }
for( auto item : currentPcb->Drawings() ) for( BOARD_ITEM* item : currentPcb->Drawings() )
{ {
if( !oldBuffer->ContainsItem( item ) ) if( !oldBuffer->ContainsItem( item ) )
{ {
ITEM_PICKER picker( item, UR_NEW ); ITEM_PICKER picker( nullptr, item, UR_NEW );
oldBuffer->PushItem( picker ); oldBuffer->PushItem( picker );
} }
} }
@ -345,8 +344,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
{ {
if( !oldBuffer->ContainsItem( (EDA_ITEM*) currentPcb->GetArea( ii ) ) ) if( !oldBuffer->ContainsItem( (EDA_ITEM*) currentPcb->GetArea( ii ) ) )
{ {
ITEM_PICKER picker( (EDA_ITEM*) currentPcb->GetArea( ITEM_PICKER picker( nullptr, (EDA_ITEM*) currentPcb->GetArea( ii ), UR_NEW );
ii ), UR_NEW );
oldBuffer->PushItem( picker ); oldBuffer->PushItem( picker );
} }
} }
@ -354,7 +352,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
if( oldBuffer->GetCount() ) if( oldBuffer->GetCount() )
{ {
OnModify(); OnModify();
GetScreen()->PushCommandToUndoList( oldBuffer ); PushCommandToUndoList( oldBuffer );
} }
else else
{ {

View File

@ -231,8 +231,8 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars()
else else
m_mainToolBar->Toggle( PCB_ACTIONS::saveToLibrary, IsContentModified() ); m_mainToolBar->Toggle( PCB_ACTIONS::saveToLibrary, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );
m_mainToolBar->Toggle( PCB_ACTIONS::footprintProperties, GetBoard()->GetFirstModule() ); m_mainToolBar->Toggle( PCB_ACTIONS::footprintProperties, GetBoard()->GetFirstModule() );
m_mainToolBar->Refresh(); m_mainToolBar->Refresh();

View File

@ -707,8 +707,8 @@ void PCB_EDIT_FRAME::SyncToolbars()
int zoneMode = opts.m_DisplayZonesMode; int zoneMode = opts.m_DisplayZonesMode;
m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );
#if defined(KICAD_SCRIPTING_WXPYTHON) #if defined(KICAD_SCRIPTING_WXPYTHON)
if( IsWxPythonLoaded() ) if( IsWxPythonLoaded() )

View File

@ -220,10 +220,7 @@ int FOOTPRINT_EDITOR_TOOLS::ImportFootprint( const TOOL_EVENT& aEvent )
if( m_frame->GetBoard()->GetFirstModule() ) if( m_frame->GetBoard()->GetFirstModule() )
m_frame->GetBoard()->GetFirstModule()->ClearFlags(); m_frame->GetBoard()->GetFirstModule()->ClearFlags();
// Clear undo and redo lists because we don't have handling to in frame()->ClearUndoRedoList();
// 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();
m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true ); m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true );
m_frame->OnModify(); m_frame->OnModify();

View File

@ -290,7 +290,7 @@ int PCB_EDITOR_CONTROL::PageSettings( const TOOL_EVENT& aEvent )
{ {
PICKED_ITEMS_LIST undoCmd; PICKED_ITEMS_LIST undoCmd;
WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( m_frame ); 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 ); undoCmd.PushItem( wrapper );
m_frame->SaveCopyInUndoList( undoCmd, UR_PAGESETTINGS ); m_frame->SaveCopyInUndoList( undoCmd, UR_PAGESETTINGS );

View File

@ -183,7 +183,7 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCo
const wxPoint& aTransformPoint ) const wxPoint& aTransformPoint )
{ {
PICKED_ITEMS_LIST commandToUndo; PICKED_ITEMS_LIST commandToUndo;
commandToUndo.PushItem( ITEM_PICKER( aItem, aCommandType ) ); commandToUndo.PushItem( ITEM_PICKER( nullptr, aItem, aCommandType ) );
SaveCopyInUndoList( commandToUndo, aCommandType, aTransformPoint ); SaveCopyInUndoList( commandToUndo, aCommandType, aTransformPoint );
} }
@ -246,7 +246,7 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis
clone->Reference().ClearEditFlags(); clone->Reference().ClearEditFlags();
clone->Value().ClearEditFlags(); clone->Value().ClearEditFlags();
ITEM_PICKER picker( item, UR_CHANGED ); ITEM_PICKER picker( nullptr, item, UR_CHANGED );
picker.SetLink( clone ); picker.SetLink( clone );
commandToUndo->PushItem( picker ); commandToUndo->PushItem( picker );
@ -315,10 +315,10 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis
if( commandToUndo->GetCount() ) if( commandToUndo->GetCount() )
{ {
/* Save the copy in undo list */ /* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo ); PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after a new command one cannot redo a command */ /* Clear redo list, because after a new command one cannot redo a command */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); ClearUndoORRedoList( m_RedoList );
} }
else else
{ {
@ -334,21 +334,21 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
if( UndoRedoBlocked() ) if( UndoRedoBlocked() )
return; return;
if( GetScreen()->GetUndoCommandCount() <= 0 ) if( GetUndoCommandCount() <= 0 )
return; return;
// Inform tools that undo command was issued // Inform tools that undo command was issued
m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } );
// Get the old list // Get the old list
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* List = PopCommandFromUndoList();
// Undo the command // Undo the command
PutDataInPreviousState( List, false ); PutDataInPreviousState( List, false );
// Put the old list in RedoList // Put the old list in RedoList
List->ReversePickersListOrder(); List->ReversePickersListOrder();
GetScreen()->PushCommandToRedoList( List ); PushCommandToRedoList( List );
OnModify(); OnModify();
@ -363,21 +363,21 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
if( UndoRedoBlocked() ) if( UndoRedoBlocked() )
return; return;
if( GetScreen()->GetRedoCommandCount() == 0 ) if( GetRedoCommandCount() == 0 )
return; return;
// Inform tools that redo command was issued // Inform tools that redo command was issued
m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } );
// Get the old list // Get the old list
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); PICKED_ITEMS_LIST* List = PopCommandFromRedoList();
// Redo the command // Redo the command
PutDataInPreviousState( List, true ); PutDataInPreviousState( List, true );
// Put the old list in UndoList // Put the old list in UndoList
List->ReversePickersListOrder(); List->ReversePickersListOrder();
GetScreen()->PushCommandToUndoList( List ); PushCommandToUndoList( List );
OnModify(); 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 ) if( aItemCount == 0 )
return; return;
@ -611,7 +611,7 @@ void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount
void PCB_BASE_EDIT_FRAME::RollbackFromUndo() void PCB_BASE_EDIT_FRAME::RollbackFromUndo()
{ {
PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* undo = PopCommandFromUndoList();
PutDataInPreviousState( undo, false ); PutDataInPreviousState( undo, false );
undo->ClearListAndDeleteItems(); undo->ClearListAndDeleteItems();

View File

@ -163,7 +163,7 @@ int SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb, int aNetCode, LA
ZONE_CONTAINER* zoneDup = new ZONE_CONTAINER( *zone ); ZONE_CONTAINER* zoneDup = new ZONE_CONTAINER( *zone );
zoneDup->SetParent( aPcb ); zoneDup->SetParent( aPcb );
ITEM_PICKER picker( zone, UR_CHANGED ); ITEM_PICKER picker( nullptr, zone, UR_CHANGED );
picker.SetLink( zoneDup ); picker.SetLink( zoneDup );
aPickList.PushItem( picker ); aPickList.PushItem( picker );
copyCount++; copyCount++;

View File

@ -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& ) void ROUTER_TOOL::NeighboringSegmentFilter( const VECTOR2I&, GENERAL_COLLECTOR& )
{ {
} }