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 ) :
EDA_ITEM( aParent, aType )
{
m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
m_Initialized = false;
m_ScreenNumber = 1;
m_NumberOfScreens = 1; // Hierarchy: Root: ScreenNumber = 1
@ -70,55 +69,6 @@ void BASE_SCREEN::InitDataPoints( const wxSize& aPageSizeIU )
}
void BASE_SCREEN::ClearUndoRedoList()
{
ClearUndoORRedoList( m_UndoList );
ClearUndoORRedoList( m_RedoList );
}
void BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem )
{
m_UndoList.PushCommand( aNewitem );
// Delete the extra items, if count max reached
if( m_UndoRedoCountMax > 0 )
{
int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 )
ClearUndoORRedoList( m_UndoList, extraitems );
}
}
void BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem )
{
m_RedoList.PushCommand( aNewitem );
// Delete the extra items, if count max reached
if( m_UndoRedoCountMax > 0 )
{
int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 )
ClearUndoORRedoList( m_RedoList, extraitems );
}
}
PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromUndoList( )
{
return m_UndoList.PopCommand();
}
PICKED_ITEMS_LIST* BASE_SCREEN::PopCommandFromRedoList( )
{
return m_RedoList.PopCommand();
}
#if defined(DEBUG)
void BASE_SCREEN::Show( int nestLevel, std::ostream& os ) const

View File

@ -81,6 +81,7 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
m_hasAutoSave( false ),
m_autoSaveState( false ),
m_autoSaveInterval(-1 ),
m_UndoRedoCountMax( DEFAULT_MAX_UNDO_ITEMS ),
m_userUnits( EDA_UNITS::MILLIMETRES )
{
m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
@ -156,10 +157,10 @@ EDA_BASE_FRAME::~EDA_BASE_FRAME()
delete m_autoSaveTimer;
delete m_fileHistory;
ClearUndoRedoList();
if( SupportsShutdownBlockReason() )
{
RemoveShutdownBlockReason();
}
}
@ -793,6 +794,55 @@ bool EDA_BASE_FRAME::IsContentModified()
}
void EDA_BASE_FRAME::ClearUndoRedoList()
{
ClearUndoORRedoList( m_UndoList );
ClearUndoORRedoList( m_RedoList );
}
void EDA_BASE_FRAME::PushCommandToUndoList( PICKED_ITEMS_LIST* aNewitem )
{
m_UndoList.PushCommand( aNewitem );
// Delete the extra items, if count max reached
if( m_UndoRedoCountMax > 0 )
{
int extraitems = GetUndoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 )
ClearUndoORRedoList( m_UndoList, extraitems );
}
}
void EDA_BASE_FRAME::PushCommandToRedoList( PICKED_ITEMS_LIST* aNewitem )
{
m_RedoList.PushCommand( aNewitem );
// Delete the extra items, if count max reached
if( m_UndoRedoCountMax > 0 )
{
int extraitems = GetRedoCommandCount() - m_UndoRedoCountMax;
if( extraitems > 0 )
ClearUndoORRedoList( m_RedoList, extraitems );
}
}
PICKED_ITEMS_LIST* EDA_BASE_FRAME::PopCommandFromUndoList( )
{
return m_UndoList.PopCommand();
}
PICKED_ITEMS_LIST* EDA_BASE_FRAME::PopCommandFromRedoList( )
{
return m_RedoList.PopCommand();
}
void EDA_BASE_FRAME::ChangeUserUnits( EDA_UNITS aUnits )
{
SetUserUnits( aUnits );

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.first_run_shown = m_firstRunDialogSetting;
if( GetScreen() )
aCfg->m_System.max_undo_items = GetScreen()->GetMaxUndoItems();
aCfg->m_System.max_undo_items = GetMaxUndoItems();
m_galDisplayOptions.WriteConfig( *window );

View File

@ -28,12 +28,34 @@
#include <undo_redo_container.h>
/*
ITEM_PICKER::ITEM_PICKER( EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus )
{
m_undoRedoStatus = aUndoRedoStatus;
SetItem( aItem );
m_pickerFlags = 0;
m_link = nullptr;
m_screen = nullptr;
}
*/
ITEM_PICKER::ITEM_PICKER()
{
m_undoRedoStatus = UR_UNSPECIFIED;
SetItem( nullptr );
m_pickerFlags = 0;
m_link = NULL;
m_screen = nullptr;
}
ITEM_PICKER::ITEM_PICKER( BASE_SCREEN* aScreen, EDA_ITEM* aItem, UNDO_REDO_T aUndoRedoStatus )
{
m_undoRedoStatus = aUndoRedoStatus;
SetItem( aItem );
m_pickerFlags = 0;
m_link = NULL;
m_screen = aScreen;
}
@ -144,6 +166,15 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
}
BASE_SCREEN* PICKED_ITEMS_LIST::GetScreenForItem( unsigned int aIdx ) const
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetScreen();
return NULL;
}
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const
{
if( aIdx < m_ItemsList.size() )

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

View File

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

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.
*
@ -30,11 +25,8 @@
#include <fctsys.h>
#include <sch_edit_frame.h>
#include <sch_draw_panel.h>
#include <bitmaps.h>
#include <confirm.h>
#include <invoke_sch_dialog.h>
#include <dialog_annotate_base.h>
#include <eeschema_settings.h>
#include <kiface_i.h>
@ -59,7 +51,7 @@ private:
/// Initialises member variables
void InitValues();
void OnClearAnnotationCmpClick( wxCommandEvent& event ) override;
void OnClearAnnotationClick( wxCommandEvent& event ) override;
void OnCloseClick( wxCommandEvent& event ) override;
void OnClose( wxCloseEvent& event ) override;
void OnApplyClick( wxCommandEvent& event ) override;
@ -132,7 +124,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
void DIALOG_ANNOTATE::InitValues()
{
auto cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
int option;
// These are always reset to attempt to keep the user out of trouble...
@ -144,12 +136,8 @@ void DIALOG_ANNOTATE::InitValues()
switch( option )
{
default:
case 0:
m_rbSortBy_X_Position->SetValue( true );
break;
case 1:
m_rbSortBy_Y_Position->SetValue( true );
break;
case 0: m_rbSortBy_X_Position->SetValue( true ); break;
case 1: m_rbSortBy_Y_Position->SetValue( true ); break;
}
option = cfg->m_AnnotatePanel.method;
@ -157,15 +145,9 @@ void DIALOG_ANNOTATE::InitValues()
switch( option )
{
default:
case 0:
m_rbFirstFree->SetValue( true );
break;
case 1:
m_rbSheetX100->SetValue( true );
break;
case 2:
m_rbSheetX1000->SetValue( true );
break;
case 0: m_rbFirstFree->SetValue( true ); break;
case 1: m_rbSheetX100->SetValue( true ); break;
case 2: m_rbSheetX1000->SetValue( true ); break;
}
m_textNumberAfter->SetValue( wxT( "0" ) );
@ -194,26 +176,6 @@ void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event )
void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
{
wxString message;
// Ask for confirmation of destructive actions.
if( GetResetItems() )
{
if( GetLevel() )
message += _( "Clear and annotate all of the symbols on the entire schematic?" );
else
message += _( "Clear and annotate all of the symbols on the current sheet?" );
message += _( "\n\nThis operation will change the current annotation and cannot be undone." );
KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
dlg.SetOKLabel( _( "Clear and Annotate" ) );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_CANCEL )
return;
}
m_MessageWindow->Clear();
REPORTER& reporter = m_MessageWindow->Reporter();
m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message
@ -222,7 +184,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
(ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(),
GetResetItems() , true, GetLockUnits(), reporter );
m_MessageWindow->Flush( true ); // Now update to show all messages
m_MessageWindow->Flush( true ); // Now update to show all messages
m_Parent->GetCanvas()->Refresh();
@ -241,25 +203,11 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
}
void DIALOG_ANNOTATE::OnClearAnnotationCmpClick( wxCommandEvent& event )
void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event )
{
wxString message;
bool appendUndo = false;
if( GetLevel() )
message = _( "Clear the existing annotation for the entire schematic?" );
else
message = _( "Clear the existing annotation for the current sheet?" );
message += _( "\n\nThis operation will clear the existing annotation and cannot be undone." );
KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
dlg.SetOKLabel( _( "Clear Annotation" ) );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_CANCEL )
return;
m_Parent->DeleteAnnotation( !GetLevel() );
m_Parent->DeleteAnnotation( !GetLevel(), &appendUndo );
m_btnClear->Enable( false );
}

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/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -35,10 +35,10 @@ DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, con
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxString m_rbScopeChoices[] = { _("Use the entire schematic"), _("Use the current page only") };
wxString m_rbScopeChoices[] = { _("Entire schematic"), _("Current sheet only") };
int m_rbScopeNChoices = sizeof( m_rbScopeChoices ) / sizeof( wxString );
m_rbScope = new wxRadioBox( this, wxID_ANY, _("Scope:"), wxDefaultPosition, wxDefaultSize, m_rbScopeNChoices, m_rbScopeChoices, 1, wxRA_SPECIFY_COLS );
m_rbScope->SetSelection( 0 );
m_rbScope->SetSelection( 1 );
fgSizer1->Add( m_rbScope, 0, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer1;
@ -148,7 +148,7 @@ DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, con
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) );
m_btnClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this );
m_btnClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationClick ), NULL, this );
m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCloseClick ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this );
}
@ -157,7 +157,7 @@ DIALOG_ANNOTATE_BASE::~DIALOG_ANNOTATE_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ANNOTATE_BASE::OnClose ) );
m_btnClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this );
m_btnClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationClick ), NULL, this );
m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCloseClick ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this );

View File

@ -14,7 +14,6 @@
<property name="file">dialog_annotate_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_annotate_base</property>
@ -26,7 +25,6 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
@ -165,7 +163,7 @@
<property name="caption"></property>
<property name="caption_visible">1</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="context_help"></property>
<property name="context_menu">1</property>
@ -197,7 +195,7 @@
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property>
@ -1018,7 +1016,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnClearAnnotationCmpClick</event>
<event name="OnButtonClick">OnClearAnnotationClick</event>
</object>
</object>
<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/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -69,7 +69,7 @@ class DIALOG_ANNOTATE_BASE : public DIALOG_SHIM
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnClearAnnotationCmpClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClearAnnotationClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCloseClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); }

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

View File

@ -211,10 +211,10 @@ bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow()
PICKED_ITEMS_LIST pickedItems;
STROKE_PARAMS stroke;
for( auto& strokeItem : m_strokeItems )
pickedItems.PushItem( ITEM_PICKER( strokeItem, UR_CHANGED ) );
for( SCH_ITEM* strokeItem : m_strokeItems )
pickedItems.PushItem( ITEM_PICKER( m_frame->GetScreen(), strokeItem, UR_CHANGED ) );
m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED );
m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED, false );
for( auto& strokeItem : m_strokeItems )
{

View File

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

View File

@ -97,7 +97,10 @@ bool DIALOG_EDIT_SHEET_PIN::TransferDataToWindow()
bool DIALOG_EDIT_SHEET_PIN::TransferDataFromWindow()
{
if( !m_sheetPin->IsNew() )
m_frame->SaveCopyInUndoList( (SCH_ITEM*) m_sheetPin->GetParent(), UR_CHANGED );
{
SCH_SHEET* parentSheet = m_sheetPin->GetParent();
m_frame->SaveCopyInUndoList( m_frame->GetScreen(), parentSheet, UR_CHANGED, false );
}
m_sheetPin->SetText( EscapeString( m_comboName->GetValue(), CTX_NETNAME ) );
// Currently, eeschema uses only the text width as text size,

View File

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

View File

@ -171,10 +171,10 @@ bool DIALOG_JUNCTION_PROPS::TransferDataFromWindow()
{
PICKED_ITEMS_LIST pickedItems;
for( auto& junction : m_junctions )
pickedItems.PushItem( ITEM_PICKER( junction, UR_CHANGED ) );
for( SCH_JUNCTION* junction : m_junctions )
pickedItems.PushItem( ITEM_PICKER( m_frame->GetScreen(), junction, UR_CHANGED ) );
m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED );
m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED, false );
for( auto& junction : m_junctions )
{

View File

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

View File

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

View File

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

View File

@ -34,17 +34,14 @@ class SCH_COMPONENT;
class SCH_SCREEN;
class SCH_EDIT_FRAME;
using std::set;
using std::list;
/**
* Dialog to update component fields (i.e. restore them from the original library symbols).
*/
class DIALOG_UPDATE_FIELDS : public DIALOG_UPDATE_FIELDS_BASE
{
public:
DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, const list<SCH_COMPONENT*>& aComponents,
bool aCreateUndoEntry = true );
DIALOG_UPDATE_FIELDS( SCH_EDIT_FRAME* aParent, SCH_COMPONENT* aComponent,
bool aCreateUndoEntry );
private:
bool TransferDataFromWindow() override;
@ -66,16 +63,14 @@ private:
checkAll( false );
}
///> Parent frame
SCH_EDIT_FRAME* m_frame;
///> Set of field names that should have values updated
set<wxString> m_updateFields;
std::set<wxString> m_updateFields;
///> 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;
};

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.
RecalculateConnections( GLOBAL_CLEANUP );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
ClearUndoRedoList();
GetScreen()->m_Initialized = true;
}
@ -872,10 +872,11 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
}
}
}
// Only perform the dangling end test on root sheet.
GetScreen()->TestDanglingEnds();
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
SetSheetNumberAndCount();

View File

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

View File

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

View File

@ -86,8 +86,8 @@ int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller );
/// Update symbol fields
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller,
const std::list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry );
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller, SCH_COMPONENT* aSpecificComponent = nullptr,
bool aCreateUndoEntry = true );
/**
* 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();
SetScreen( m_dummyScreen );
GetScreen()->m_Center = true;
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
@ -726,7 +725,7 @@ void LIB_EDIT_FRAME::emptyScreen()
SetCurLib( wxEmptyString );
SetCurPart( nullptr );
SetScreen( m_dummyScreen );
m_dummyScreen->ClearUndoRedoList();
ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
Refresh();
}
@ -909,3 +908,20 @@ bool LIB_EDIT_FRAME::IsContentModified()
return false;
}
void LIB_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
{
if( aItemCount == 0 )
return;
for( auto& command : aList.m_CommandsList )
{
command->ClearListAndDeleteItems();
delete command;
}
aList.m_CommandsList.clear();
}

View File

@ -342,6 +342,20 @@ public:
void RollbackPartFromUndo();
/**
* Free the undo or redo list from \a aList element.
*
* - Wrappers are deleted.
* - data pointed by wrappers are deleted if not in use in schematic
* i.e. when they are copy of a schematic item or they are no more in use (DELETED)
*
* @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list.
* So this function can be called to remove old commands
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
private:
/**
* Read a component symbol file (*.sym ) and add graphic items to the current component.

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
m_SyncPinEdit = !GetCurPart()->UnitsLocked();
GetScreen()->ClearUndoRedoList();
ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );

View File

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

View File

@ -95,10 +95,10 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return m_my_part && GetScreen() && GetScreen()->GetUndoCommandCount() != 0;
return m_my_part && GetUndoCommandCount() != 0;
};
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return m_my_part && GetScreen() && GetScreen()->GetRedoCommandCount() != 0;
return m_my_part && GetRedoCommandCount() != 0;
};
auto haveSymbolCondition = [ this ] ( const SELECTION& sel ) {
return m_my_part != nullptr;

View File

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

View File

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

View File

@ -249,13 +249,13 @@ public:
* Add an item to the screen (and view)
* aScreen is the screen the item is located on, if not the current screen
*/
void AddToScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen = nullptr );
void AddToScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen );
/**
* Remove an item from the screen (and view)
* aScreen is the screen the item is located on, if not the current screen
*/
void RemoveFromScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen = nullptr );
void RemoveFromScreen( EDA_ITEM* aItem, SCH_SCREEN* aScreen );
/**
* Mark an item for refresh.

View File

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

View File

@ -259,7 +259,7 @@ public:
* Add an item to the schematic and adds the changes to the undo/redo container.
* @param aUndoAppend True if the action should be appended to the current undo record.
*/
void AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppend = false );
void AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, bool aUndoAppend );
/**
* Run the Find or Find & Replace dialog.
@ -423,7 +423,7 @@ public:
* @param aCurrentSheetOnly Clear only the annotation for the current sheet if true.
* Otherwise clear the entire schematic annotation.
*/
void DeleteAnnotation( bool aCurrentSheetOnly );
void DeleteAnnotation( bool aCurrentSheetOnly, bool* appendUndo );
/**
* Annotate the components in the schematic that are not currently annotated.
@ -572,7 +572,7 @@ public:
*/
bool AskToSaveChanges();
SCH_JUNCTION* AddJunction( const wxPoint& aPos, bool aAppendToUndo = false,
SCH_JUNCTION* AddJunction( SCH_SCREEN* aScreen, const wxPoint& aPos, bool aAppendToUndo,
bool aFinal = true );
/**
@ -792,7 +792,7 @@ public:
/**
* Create a copy of the current schematic item, and put it in the undo list.
*
* flag_type_command =
* aTypeCommand =
* UR_CHANGED
* UR_NEW
* UR_DELETED
@ -804,21 +804,19 @@ public:
*
* @note
* Edit wires and buses is a bit complex.
* because when a new wire is added, a lot of modifications in wire list is made
* (wire concatenation): modified items, deleted items and new items
* so flag_type_command is UR_WIRE_IMAGE: the struct ItemToCopy is a list of
* wires saved in Undo List (for Undo or Redo commands, saved wires will be
* exchanged with current wire list
* When a new wire is added, a lot of modifications are made in the wire list (merging,
* junctions, etc.). We therefore set the aTypeCommand to UR_WIRE_IMAGE and save the whole
* schebang.
*
* @param aItemToCopy = the schematic item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
* @param aTransformPoint = the reference point of the transformation for commands like move
*/
void SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
void SaveCopyInUndoList( SCH_SCREEN* aScreen,
SCH_ITEM* aItemToCopy,
UNDO_REDO_T aTypeCommand,
bool aAppend = false,
bool aAppend,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
@ -827,12 +825,11 @@ public:
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aAppend = add the item to the previous undo list
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
* @param aTransformPoint = the reference point of the transformation for commands like move
*/
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
bool aAppend = false,
bool aAppend,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
@ -843,6 +840,20 @@ public:
*/
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand );
/**
* Free the undo or redo list from \a aList element.
*
* - Wrappers are deleted.
* - data pointed by wrappers are deleted if not in use in schematic
* i.e. when they are copy of a schematic item or they are no more in use (DELETED)
*
* @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list.
* So this function can be called to remove old commands
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
/**
* Clone \a aItem and owns that clone in this container.
*/

View File

@ -85,7 +85,6 @@ SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) :
SCH_SCREEN::~SCH_SCREEN()
{
clearLibSymbols();
ClearUndoRedoList();
FreeDrawList();
}
@ -801,21 +800,6 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter )
}
void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
{
if( aItemCount == 0 )
return;
for( auto& command : aList.m_CommandsList )
{
command->ClearListAndDeleteItems();
delete command;
}
aList.m_CommandsList.clear();
}
void SCH_SCREEN::ClearDrawingState()
{
for( auto item : Items() )
@ -1230,13 +1214,6 @@ void SCH_SCREENS::buildScreenList( SCH_SHEET* aSheet )
}
void SCH_SCREENS::ClearAnnotation()
{
for( SCH_SCREEN* screen : m_screens )
screen->ClearAnnotation( NULL );
}
void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList )
{
SCH_SCREEN* first = GetFirst();

View File

@ -330,24 +330,6 @@ public:
*/
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.
*/
@ -560,11 +542,6 @@ public:
SCH_SCREEN* GetScreen( unsigned int aIndex ) const;
SCH_SHEET* GetSheet( unsigned int aIndex ) const;
/**
* Clear the annotation for all components in the hierarchy.
*/
void ClearAnnotation();
/**
* Clear the annotation for the components inside new sheetpaths
* when a complex hierarchy is modified and new sheetpaths added

View File

@ -23,26 +23,17 @@
*/
#include <fctsys.h>
#include <sch_draw_panel.h>
#include <sch_edit_frame.h>
#include <tool/tool_manager.h>
#include <general.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_no_connect.h>
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_bitmap.h>
#include <sch_view.h>
#include <tools/ee_selection_tool.h>
#include <ws_proxy_undo_item.h>
#include <tool/actions.h>
/* Functions to undo and redo edit commands.
* commands to undo are stored in CurrentScreen->m_UndoList
* commands to redo are stored in CurrentScreen->m_RedoList
*
* m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
* Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
@ -103,7 +94,8 @@
* swapped data is data modified by editing, so not all values are swapped
*/
void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen,
SCH_ITEM* aItem,
UNDO_REDO_T aCommandType,
bool aAppend,
const wxPoint& aTransformPoint )
@ -117,7 +109,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
aItem->SetConnectivityDirty();
if( aAppend )
commandToUndo = GetScreen()->PopCommandFromUndoList();
commandToUndo = PopCommandFromUndoList();
if( !commandToUndo )
{
@ -125,7 +117,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
commandToUndo->m_TransformPoint = aTransformPoint;
}
ITEM_PICKER itemWrapper( aItem, aCommandType );
ITEM_PICKER itemWrapper( aScreen, aItem, aCommandType );
itemWrapper.SetFlags( aItem->GetFlags() );
switch( aCommandType )
@ -151,10 +143,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
if( commandToUndo->GetCount() )
{
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
ClearUndoORRedoList( m_RedoList );
}
else
{
@ -175,7 +167,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
// Can't append a WIRE IMAGE, so fail to a new undo point
if( aAppend )
commandToUndo = GetScreen()->PopCommandFromUndoList();
commandToUndo = PopCommandFromUndoList();
if( !commandToUndo )
{
@ -247,10 +239,10 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
if( commandToUndo->GetCount() )
{
/* Save the copy in undo list */
GetScreen()->PushCommandToUndoList( commandToUndo );
PushCommandToUndoList( commandToUndo );
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
ClearUndoORRedoList( m_RedoList );
}
else // Should not occur
{
@ -275,13 +267,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( status == UR_NEW )
{
// new items are deleted on undo
RemoveFromScreen( eda_item );
RemoveFromScreen( eda_item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
aList->SetPickedItemStatus( UR_DELETED, (unsigned) ii );
}
else if( status == UR_DELETED )
{
// deleted items are re-inserted on undo
AddToScreen( eda_item );
AddToScreen( eda_item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
aList->SetPickedItemStatus( UR_NEW, (unsigned) ii );
}
else if( status == UR_PAGESETTINGS )
@ -299,7 +291,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
SCH_ITEM* item = (SCH_ITEM*) eda_item;
SCH_ITEM* alt_item = (SCH_ITEM*) aList->GetPickedItemLink( (unsigned) ii );
RemoveFromScreen( item );
RemoveFromScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
switch( status )
{
@ -343,7 +335,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
break;
}
AddToScreen( item );
AddToScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) );
}
}
@ -359,7 +351,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
void SCH_EDIT_FRAME::RollbackSchematicFromUndo()
{
PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList();
PICKED_ITEMS_LIST* undo = PopCommandFromUndoList();
if( undo )
{
@ -375,3 +367,20 @@ void SCH_EDIT_FRAME::RollbackSchematicFromUndo()
SyncView();
GetCanvas()->Refresh();
}
void SCH_EDIT_FRAME::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
{
if( aItemCount == 0 )
return;
for( auto& command : aList.m_CommandsList )
{
command->ClearListAndDeleteItems();
delete command;
}
aList.m_CommandsList.clear();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -137,10 +137,17 @@ protected:
wxASSERT( editFrame );
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
editFrame->SaveCopyInUndoList(
static_cast<SCH_ITEM*>( aItem->GetParent() ), UR_CHANGED, aAppend );
{
editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
static_cast<SCH_ITEM*>( aItem->GetParent() ),
UR_CHANGED, aAppend );
}
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 ) )

View File

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

View File

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

View File

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

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

View File

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

View File

@ -33,7 +33,6 @@
#include <eda_draw_frame.h>
#include <base_struct.h>
#include <undo_redo_container.h>
#include <common.h>
@ -46,7 +45,6 @@ class BASE_SCREEN : public EDA_ITEM
private:
bool m_FlagModified; ///< Indicates current drawing has been modified.
bool m_FlagSave; ///< Indicates automatic file save.
int m_UndoRedoCountMax; ///< undo/Redo command Max depth
/**
* The cross hair position in logical (drawing) units. The cross hair is not the cursor
@ -78,12 +76,8 @@ public:
bool m_Initialized;
// Undo/redo list of commands
UNDO_REDO_CONTAINER m_UndoList; ///< Objects list for the undo command (old data)
UNDO_REDO_CONTAINER m_RedoList; ///< Objects list for the redo command (old data)
int m_ScreenNumber;
int m_NumberOfScreens;
int m_ScreenNumber;
int m_NumberOfScreens;
public:
BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType = SCREEN_T );
@ -102,83 +96,6 @@ public:
void InitDataPoints( const wxSize& aPageSizeInternalUnits );
/* general Undo/Redo command control */
/**
* Function ClearUndoORRedoList (virtual).
* this function must remove the aItemCount old commands from aList
* and delete commands, pickers and picked items if needed
* Because picked items must be deleted only if they are not in use, this
* is a virtual pure function that must be created for SCH_SCREEN and
* PCB_SCREEN
* @param aList = the UNDO_REDO_CONTAINER of commands
* @param aItemCount = number of old commands to delete. -1 to remove all
* old commands this will empty the list of commands.
* Commands are deleted from the older to the last.
*/
virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 )
{ }
/**
* Function ClearUndoRedoList
* clear undo and redo list, using ClearUndoORRedoList()
* picked items are deleted by ClearUndoORRedoList() according to their
* status
*/
virtual void ClearUndoRedoList();
/**
* Function PushCommandToUndoList
* add a command to undo in undo list
* delete the very old commands when the max count of undo commands is
* reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
/**
* Function PushCommandToRedoList
* add a command to redo in redo list
* delete the very old commands when the max count of redo commands is
* reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
/** PopCommandFromUndoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromUndoList();
/** PopCommandFromRedoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromRedoList();
int GetUndoCommandCount() const
{
return m_UndoList.m_CommandsList.size();
}
int GetRedoCommandCount() const
{
return m_RedoList.m_CommandsList.size();
}
int GetMaxUndoItems() const { return m_UndoRedoCountMax; }
void SetMaxUndoItems( int aMax )
{
if( aMax >= 0 && aMax < ABS_MAX_UNDO_ITEMS )
m_UndoRedoCountMax = aMax;
else
{
wxFAIL_MSG( "Maximum undo items not within limits" );
m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
}
}
void SetModify() { m_FlagModified = true; }
void ClrModify() { m_FlagModified = false; }

View File

@ -48,6 +48,7 @@
#include <kiway_holder.h>
#include <tool/tools_holder.h>
#include <widgets/ui_common.h>
#include <undo_redo_container.h>
// Option for main frames
#define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS
@ -85,6 +86,9 @@ enum id_librarytype {
LIBRARY_TYPE_SYMBOL
};
#define DEFAULT_MAX_UNDO_ITEMS 0
#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2)
wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent );
@ -137,13 +141,23 @@ protected:
SETTINGS_MANAGER* m_settingsManager;
FILE_HISTORY* m_fileHistory; // The frame's recently opened file list
FILE_HISTORY* m_fileHistory; // The frame's recently opened file list
bool m_hasAutoSave;
bool m_autoSaveState;
int m_autoSaveInterval; // The auto save interval time in seconds.
wxTimer* m_autoSaveTimer;
bool m_FlagModified; // Indicates current drawing has been modified.
bool m_FlagSave; // Indicates automatic file save.
int m_UndoRedoCountMax; // undo/Redo command Max depth
public:
// Undo/redo list of commands
UNDO_REDO_CONTAINER m_UndoList; // Objects list for the undo command (old data)
UNDO_REDO_CONTAINER m_RedoList; // Objects list for the redo command (old data)
protected:
wxString m_mruPath; // Most recently used path.
EDA_UNITS m_userUnits;
@ -521,6 +535,85 @@ public:
* @return the undecorated window size
*/
wxSize GetWindowSize();
/* general Undo/Redo command control */
/**
* Function ClearUndoORRedoList (virtual).
* this function must remove the aItemCount old commands from aList
* and delete commands, pickers and picked items if needed
* Because picked items must be deleted only if they are not in use, this
* is a virtual pure function that must be created for SCH_SCREEN and
* PCB_SCREEN
* @param aList = the UNDO_REDO_CONTAINER of commands
* @param aItemCount = number of old commands to delete. -1 to remove all
* old commands this will empty the list of commands.
* Commands are deleted from the older to the last.
*/
virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 )
{ }
/**
* Function ClearUndoRedoList
* clear undo and redo list, using ClearUndoORRedoList()
* picked items are deleted by ClearUndoORRedoList() according to their
* status
*/
virtual void ClearUndoRedoList();
/**
* Function PushCommandToUndoList
* add a command to undo in undo list
* delete the very old commands when the max count of undo commands is
* reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
/**
* Function PushCommandToRedoList
* add a command to redo in redo list
* delete the very old commands when the max count of redo commands is
* reached
* ( using ClearUndoORRedoList)
*/
virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
/** PopCommandFromUndoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromUndoList();
/** PopCommandFromRedoList
* return the last command to undo and remove it from list
* nothing is deleted.
*/
virtual PICKED_ITEMS_LIST* PopCommandFromRedoList();
int GetUndoCommandCount() const
{
return m_UndoList.m_CommandsList.size();
}
int GetRedoCommandCount() const
{
return m_RedoList.m_CommandsList.size();
}
int GetMaxUndoItems() const { return m_UndoRedoCountMax; }
void SetMaxUndoItems( int aMax )
{
if( aMax >= 0 && aMax < ABS_MAX_UNDO_ITEMS )
m_UndoRedoCountMax = aMax;
else
{
wxFAIL_MSG( "Maximum undo items not within limits" );
m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
}
}
};

View File

@ -50,8 +50,6 @@ namespace KIGFX
using KIGFX::COLOR4D;
using KIGFX::RENDER_SETTINGS;
#define DEFAULT_MAX_UNDO_ITEMS 0
#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2)
#define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
#define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" )

View File

@ -22,10 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file pcb_screen.h
*/
#ifndef PCB_SCREEN_H
#define PCB_SCREEN_H
@ -34,9 +30,6 @@
#include <class_board_item.h>
class UNDO_REDO_CONTAINER;
/* Handle info to display a board */
class PCB_SCREEN : public BASE_SCREEN
{
@ -46,35 +39,11 @@ public:
PCB_LAYER_ID m_Route_Layer_BOTTOM;
public:
/**
* Constructor
* @param aPageSizeIU is the size of the initial paper page in internal units.
*/
PCB_SCREEN( const wxSize& aPageSizeIU );
~PCB_SCREEN();
/* full undo redo management : */
// use BASE_SCREEN::ClearUndoRedoList()
// use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
// use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
/**
* Function ClearUndoORRedoList
* free the undo or redo list from List element
* Wrappers are deleted.
* datas pointed by wrappers are deleted if not in use in schematic
* i.e. when they are copy of a schematic item or they are no more in use
* (DELETED)
* @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list.
* So this function can be called to remove old commands
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
};
#endif // PCB_SCREEN_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,7 +29,7 @@
#include <config_params.h>
#include <eda_draw_frame.h>
#include <pl_editor_screen.h>
#include <base_screen.h>
#include <pl_editor_layout.h>
#include <pl_draw_panel_gal.h>
@ -124,11 +124,6 @@ public:
PL_DRAW_PANEL_GAL* GetCanvas() const override;
PL_EDITOR_SCREEN* GetScreen() const override
{
return (PL_EDITOR_SCREEN*) EDA_DRAW_FRAME::GetScreen();
}
const wxPoint& GetGridOrigin() const override { return m_grid_origin; }
void SetGridOrigin( const wxPoint& aPoint ) override { m_grid_origin = aPoint; }
@ -266,9 +261,8 @@ public:
/**
* Save a copy of the description (in a S expr string) for Undo/redo commands.
* Optionally save the pageInfo and titleBlock as well.
*/
void SaveCopyInUndoList( bool aSavePageSettingsAndTitleBlock = false );
void SaveCopyInUndoList();
/** Redo the last edit:
* - Place the current edited layout in undo list
@ -288,6 +282,11 @@ public:
*/
void RollbackFromUndo();
/**
* Function ClearUndoORRedoList
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
protected:
bool saveCurrentPageLayout();

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 <macros.h>
#include <ws_data_model.h>
#include <ws_draw_item.h>
#include <pl_editor_frame.h>
#include <tool/tool_manager.h>
#include <tools/pl_selection_tool.h>
#include <ws_proxy_undo_item.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();
WS_PROXY_UNDO_ITEM* copyItem = new WS_PROXY_UNDO_ITEM( this );
ITEM_PICKER wrapper( copyItem, UR_LIBEDIT );
ITEM_PICKER wrapper( GetScreen(), copyItem, UR_LIBEDIT );
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd );
PushCommandToUndoList( lastcmd );
// Clear redo list, because after new save there is no redo to do.
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
ClearUndoORRedoList( m_RedoList );
}
@ -56,17 +54,19 @@ void PL_EDITOR_FRAME::GetLayoutFromRedoList()
{
PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetRedoCommandCount() <= 0 )
if ( GetRedoCommandCount() <= 0 )
return;
ITEM_PICKER redoWrapper = GetScreen()->PopCommandFromRedoList()->PopItem();
ITEM_PICKER redoWrapper = PopCommandFromRedoList()->PopItem();
WS_PROXY_UNDO_ITEM* redoItem = static_cast<WS_PROXY_UNDO_ITEM*>( redoWrapper.GetItem() );
bool pageSettingsAndTitleBlock = redoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
PICKED_ITEMS_LIST* undoCmd = new PICKED_ITEMS_LIST();
WS_PROXY_UNDO_ITEM* undoItem = new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr );
ITEM_PICKER undoWrapper( GetScreen(), undoItem );
undoCmd->PushItem( new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ) );
GetScreen()->PushCommandToUndoList( undoCmd );
undoCmd->PushItem( undoWrapper );
PushCommandToUndoList( undoCmd );
selTool->ClearSelection();
redoItem->Restore( this, GetCanvas()->GetView() );
@ -91,17 +91,19 @@ void PL_EDITOR_FRAME::GetLayoutFromUndoList()
{
PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetUndoCommandCount() <= 0 )
if ( GetUndoCommandCount() <= 0 )
return;
ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem();
ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem();
WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
bool pageSettingsAndTitleBlock = undoItem->Type() == WS_PROXY_UNDO_ITEM_PLUS_T;
PICKED_ITEMS_LIST* redoCmd = new PICKED_ITEMS_LIST();
WS_PROXY_UNDO_ITEM* redoItem = new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr );
ITEM_PICKER redoWrapper( GetScreen(), redoItem );
redoCmd->PushItem( new WS_PROXY_UNDO_ITEM( pageSettingsAndTitleBlock ? this : nullptr ) );
GetScreen()->PushCommandToRedoList( redoCmd );
redoCmd->PushItem( redoWrapper );
PushCommandToRedoList( redoCmd );
selTool->ClearSelection();
undoItem->Restore( this, GetCanvas()->GetView() );
@ -125,10 +127,10 @@ void PL_EDITOR_FRAME::RollbackFromUndo()
{
PL_SELECTION_TOOL* selTool = GetToolManager()->GetTool<PL_SELECTION_TOOL>();
if ( GetScreen()->GetUndoCommandCount() <= 0 )
if ( GetUndoCommandCount() <= 0 )
return;
ITEM_PICKER undoWrapper = GetScreen()->PopCommandFromUndoList()->PopItem();
ITEM_PICKER undoWrapper = PopCommandFromUndoList()->PopItem();
WS_PROXY_UNDO_ITEM* undoItem = static_cast<WS_PROXY_UNDO_ITEM*>( undoWrapper.GetItem() );
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 ) )
m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );
m_mainToolBar->Refresh();

View File

@ -85,7 +85,7 @@ int PL_EDITOR_CONTROL::SaveAs( const TOOL_EVENT& aEvent )
int PL_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent )
{
m_frame->SaveCopyInUndoList( true );
m_frame->SaveCopyInUndoList();
DIALOG_PAGES_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
dlg.SetWksFileName( m_frame->GetCurrentFileName() );

View File

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

View File

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

View File

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

View File

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

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
SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) );
SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
// Create the manager and dispatcher & route draw panel events to the dispatcher
setupTools();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -185,6 +185,26 @@ public:
COLOR_SETTINGS* GetColorSettings() override;
/* full undo redo management : */
// use EDA_BASE_FRAME::ClearUndoRedoList()
// use EDA_BASE_FRAME::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
// use EDA_BASE_FRAME::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
/**
* Function ClearUndoORRedoList
* free the undo or redo list from List element
* Wrappers are deleted.
* datas pointed by wrappers are deleted if not in use in schematic
* i.e. when they are copy of a schematic item or they are no more in use
* (DELETED)
* @param aList = the UNDO_REDO_CONTAINER to clear
* @param aItemCount = the count of items to remove. < 0 for all items
* items are removed from the beginning of the list.
* So this function can be called to remove old commands
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
protected:
/// User defined rotation angle (in tenths of a degree).
int m_rotationAngle;

View File

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

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_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)
// clear the lists
// todo: use undo/redo feature
GetScreen()->ClearUndoRedoList();
ClearUndoRedoList();
SPECCTRA_DB db;
LOCALE_IO toggle;

View File

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

View File

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

View File

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

View File

@ -220,10 +220,7 @@ int FOOTPRINT_EDITOR_TOOLS::ImportFootprint( const TOOL_EVENT& aEvent )
if( m_frame->GetBoard()->GetFirstModule() )
m_frame->GetBoard()->GetFirstModule()->ClearFlags();
// Clear undo and redo lists because we don't have handling to in
// FP editor to undo across imports (the module _is_ the board with the stack)
// todo: Abstract undo/redo stack to a higher element or keep consistent board item in fpeditor
frame()->GetScreen()->ClearUndoRedoList();
frame()->ClearUndoRedoList();
m_toolMgr->RunAction( ACTIONS::zoomFitScreen, true );
m_frame->OnModify();

View File

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

View File

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

View File

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

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& )
{
}