From aa35b98036820ab6148f78fface8e72e61161e95 Mon Sep 17 00:00:00 2001 From: charras Date: Wed, 24 Mar 2010 18:26:04 +0000 Subject: [PATCH] Eeschema: fixed some issues in undo/redo and ESC commands related to hierarchical sheets --- eeschema/busentry.cpp | 3 +- eeschema/class_drawsheet.cpp | 16 ++++++++ eeschema/hotkeys.cpp | 12 +++--- eeschema/onrightclick.cpp | 9 ++++- eeschema/operations_on_items_lists.cpp | 51 ++++++++++++++++---------- eeschema/protos.h | 12 +++++- eeschema/schedit.cpp | 12 +++--- eeschema/schematic_undo_redo.cpp | 33 +---------------- eeschema/sheet.cpp | 17 +++++++++ eeschema/sheetlab.cpp | 24 ++++++++++-- 10 files changed, 119 insertions(+), 70 deletions(-) diff --git a/eeschema/busentry.cpp b/eeschema/busentry.cpp index 851a1b9412..27b87539e9 100644 --- a/eeschema/busentry.cpp +++ b/eeschema/busentry.cpp @@ -92,8 +92,7 @@ void WinEDA_SchematicFrame::StartMoveBusEntry( SCH_BUS_ENTRY* BusEntry, if( BusEntry == NULL ) return; - if( (BusEntry->m_Flags & IS_NEW) == 0 ) // => not already in edit, save - // shape */ + if( (BusEntry->m_Flags & IS_NEW) == 0 ) // not already in edit, save shape { delete g_ItemToUndoCopy; g_ItemToUndoCopy = BusEntry->GenCopy(); diff --git a/eeschema/class_drawsheet.cpp b/eeschema/class_drawsheet.cpp index dd0b6fd3ce..b332ba362d 100644 --- a/eeschema/class_drawsheet.cpp +++ b/eeschema/class_drawsheet.cpp @@ -208,6 +208,22 @@ void SCH_SHEET::Place( WinEDA_SchematicFrame* frame, wxDC* DC ) return; } } + else /* save old text in undo list */ + { + if( g_ItemToUndoCopy && ( g_ItemToUndoCopy->Type() == Type() ) ) + { + /* restore old values and save new ones */ + SwapData( (SCH_SHEET*) g_ItemToUndoCopy ); + + /* save in undo list */ + frame->SaveCopyInUndoList( this, UR_CHANGED ); + + /* restore new values */ + SwapData( (SCH_SHEET*) g_ItemToUndoCopy ); + + SAFE_DELETE( g_ItemToUndoCopy ); + } + } SCH_ITEM::Place( frame, DC ); //puts it on the EEDrawList. if( isnew ) diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp index 79c8371a7f..52951a280f 100644 --- a/eeschema/hotkeys.cpp +++ b/eeschema/hotkeys.cpp @@ -551,7 +551,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct ); // Create the events for moving a component or other schematic item - wxCommandEvent eventMoveComponent( wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEvent eventMoveOrDragComponent( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent ); wxCommandEvent eventMoveItem( wxEVT_COMMAND_TOOL_CLICKED, ID_POPUP_SCH_MOVE_ITEM_REQUEST ); @@ -564,22 +564,24 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, { // select the correct event for moving an schematic object // and add it to the event queue + case DRAW_SHEET_STRUCT_TYPE: case TYPE_SCH_COMPONENT: - wxPostEvent( this, eventMoveComponent ); + wxPostEvent( this, eventMoveOrDragComponent ); break; case TYPE_SCH_TEXT: case TYPE_SCH_LABEL: case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_HIERLABEL: - case DRAW_SHEET_STRUCT_TYPE: case DRAW_PART_TEXT_STRUCT_TYPE: case DRAW_BUSENTRY_STRUCT_TYPE: - wxPostEvent( this, eventMoveItem ); + if( HK_Descr->m_Idcommand != HK_DRAG ) + wxPostEvent( this, eventMoveItem ); break; case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE: - wxPostEvent( this, eventMovePinsheet ); + if( HK_Descr->m_Idcommand != HK_DRAG ) + wxPostEvent( this, eventMovePinsheet ); break; case DRAW_SEGMENT_STRUCT_TYPE: diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index 952a172822..a2306135f6 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -439,11 +439,11 @@ void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel ) msg = AddHotkeyName( _( "Rotate Hierarchical Label" ), s_Schematic_Hokeys_Descr, HK_ROTATE ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, - _( "Rotate Hierarchical Label" ), rotate_glabel_xpm ); + msg, rotate_glabel_xpm ); msg = AddHotkeyName( _( "Edit Hierarchical Label" ), s_Schematic_Hokeys_Descr, HK_EDIT ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, - _( "Edit Hierarchical Label" ), edit_text_xpm ); + msg, edit_text_xpm ); msg = AddHotkeyName( _( "Delete Hierarchical Label" ), s_Schematic_Hokeys_Descr, HK_DELETE ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE, @@ -678,6 +678,11 @@ void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet ) s_Schematic_Hokeys_Descr, HK_MOVE_COMPONENT_OR_ITEM ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_sheet_xpm ); + + msg = AddHotkeyName( _( "Drag Sheet" ), s_Schematic_Hokeys_Descr, + HK_DRAG ); + ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST, + msg, move_sheet_xpm ); } if( Sheet->m_Flags ) diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp index 48ca40fb75..8341099fcd 100644 --- a/eeschema/operations_on_items_lists.cpp +++ b/eeschema/operations_on_items_lists.cpp @@ -181,79 +181,92 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList, } -/* Routine to create a new copy of given struct. +/** function DuplicateStruct + * Routine to create a new copy of given struct. * The new object is not put in draw list (not linked) + * @param aDrawStruct = the SCH_ITEM to duplicate + * @param aClone (default = false) + * if true duplicate also some parameters that must be unique + * (timestamp and sheet name) + * aClone must be false. use true only is undo/redo duplications */ -SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct ) +SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone ) { SCH_ITEM* NewDrawStruct = NULL; - if( DrawStruct == NULL ) + if( aDrawStruct == NULL ) { wxMessageBox( wxT( "DuplicateStruct error: NULL struct" ) ); return NULL; } - - switch( DrawStruct->Type() ) + + switch( aDrawStruct->Type() ) { case DRAW_POLYLINE_STRUCT_TYPE: - NewDrawStruct = ( (SCH_POLYLINE*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_POLYLINE*) aDrawStruct )->GenCopy(); break; case DRAW_SEGMENT_STRUCT_TYPE: - NewDrawStruct = ( (SCH_LINE*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_LINE*) aDrawStruct )->GenCopy(); break; case DRAW_BUSENTRY_STRUCT_TYPE: - NewDrawStruct = ( (SCH_BUS_ENTRY*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_BUS_ENTRY*) aDrawStruct )->GenCopy(); break; case DRAW_JUNCTION_STRUCT_TYPE: - NewDrawStruct = ( (SCH_JUNCTION*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_JUNCTION*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_MARKER: - NewDrawStruct = ( (SCH_MARKER*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_MARKER*) aDrawStruct )->GenCopy(); break; case DRAW_NOCONNECT_STRUCT_TYPE: - NewDrawStruct = ( (SCH_NO_CONNECT*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_NO_CONNECT*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_TEXT: - NewDrawStruct = ( (SCH_TEXT*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_TEXT*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_LABEL: - NewDrawStruct = ( (SCH_LABEL*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_LABEL*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_HIERLABEL: - NewDrawStruct = ( (SCH_HIERLABEL*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_HIERLABEL*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_GLOBALLABEL: - NewDrawStruct = ( (SCH_GLOBALLABEL*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_GLOBALLABEL*) aDrawStruct )->GenCopy(); break; case TYPE_SCH_COMPONENT: - NewDrawStruct = ( (SCH_COMPONENT*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_COMPONENT*) aDrawStruct )->GenCopy(); break; case DRAW_SHEET_STRUCT_TYPE: - NewDrawStruct = ( (SCH_SHEET*) DrawStruct )->GenCopy(); + NewDrawStruct = ( (SCH_SHEET*) aDrawStruct )->GenCopy(); + if ( aClone ) + { + ((SCH_SHEET*)NewDrawStruct)->m_SheetName = ((SCH_SHEET*)aDrawStruct)->m_SheetName; + } break; default: { wxString msg; msg << wxT( "DuplicateStruct error: unexpected StructType " ) - << DrawStruct->Type() << wxT( " " ) << DrawStruct->GetClass(); + << aDrawStruct->Type() << wxT( " " ) << aDrawStruct->GetClass(); wxMessageBox( msg ); } break; } - NewDrawStruct->m_Image = DrawStruct; + if ( aClone ) + NewDrawStruct->m_TimeStamp = aDrawStruct->m_TimeStamp; + + NewDrawStruct->m_Image = aDrawStruct; return NewDrawStruct; } diff --git a/eeschema/protos.h b/eeschema/protos.h index f6fd8d2244..227d8cf858 100644 --- a/eeschema/protos.h +++ b/eeschema/protos.h @@ -71,11 +71,21 @@ bool LibItemInBox( int x1, int y1, int x2, int y2, /************/ /* BLOCK.CPP */ /************/ -SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct ); void DeleteStruct( WinEDA_DrawPanel* panel, wxDC* DC, SCH_ITEM* DrawStruct ); +// operations_on_item_lists.cpp +/** function DuplicateStruct + * Routine to create a new copy of given struct. + * @param aDrawStruct = the SCH_ITEM to duplicate + * @param aClone (defualt = true) + * if true duplicate also some parameters that must be unique + * (timestamp and sheet name) + * aClone must be false. use true only is undo/redo duplications + */ +SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct, bool aClone = false ); + /*************/ /* LOCATE.CPP */ /*************/ diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index a9072f233f..e2767e4946 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -397,20 +397,20 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_SCH_DRAG_CMP_REQUEST: case ID_POPUP_SCH_MOVE_CMP_REQUEST: - // Ensure the struct is a component (could be a struct of a - // component, like Field, text..) - if( screen->GetCurItem()->Type() != TYPE_SCH_COMPONENT ) + // component, like Field, text..) or a hierachical sheet + if( (screen->GetCurItem()->Type() != TYPE_SCH_COMPONENT) + && (screen->GetCurItem()->Type() != DRAW_SHEET_STRUCT_TYPE) ) screen->SetCurItem( LocateSmallestComponent( screen ) ); if( screen->GetCurItem() == NULL ) break; - + // fall through case ID_POPUP_SCH_MOVE_ITEM_REQUEST: DrawPanel->MouseToCursorSchema(); if( id == ID_POPUP_SCH_DRAG_CMP_REQUEST ) { - // The easiest way to handle a drag component is to simulate a - // block drag command + // The easiest way to handle a drag component or sheet command + // is to simulate a block drag command if( screen->m_BlockLocate.m_State == STATE_NO_BLOCK ) { if( !HandleBlockBegin( &dc, BLOCK_DRAG, diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 953d8ad950..f2a8a6cbfc 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -180,35 +180,6 @@ void SwapData( EDA_BaseStruct* aItem, EDA_BaseStruct* aImage ) } -/** function CloneStruct - * must be used only in undo/redo functions - * - * Routine to create a new copy of given schùatic object. - * It does the same job as DuplicateStruct, but - * but clone time stamp and sheet name when cloning a SCH_SHEET objects - * (because time stamp and sheets name must be unique - * DuplicateStruct does not copy these members - */ -static SCH_ITEM* CloneStruct( SCH_ITEM* aDrawStruct ) -{ - SCH_ITEM* item = DuplicateStruct( aDrawStruct ); - if( item == NULL ) - return NULL; - - item->m_TimeStamp = aDrawStruct->m_TimeStamp; - switch( item->Type() ) - { - case DRAW_SHEET_STRUCT_TYPE: - ((SCH_SHEET*)item)->m_SheetName = ((SCH_SHEET*)aDrawStruct)->m_SheetName; - break; - - default: - break; - } - - return item; -} - /** function SaveCopyInUndoList * Create a copy of the current schematic item, and put it in the undo list. @@ -260,7 +231,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( SCH_ITEM* aItem, switch( aCommandType ) { case UR_CHANGED: /* Create a copy of item */ - CopyOfItem = CloneStruct( aItem ); + CopyOfItem = DuplicateStruct( aItem, true ); itemWrapper.m_Link = CopyOfItem; if ( CopyOfItem ) commandToUndo->PushItem( itemWrapper ); @@ -330,7 +301,7 @@ void WinEDA_SchematicFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, * If this link is not null, the copy is already done */ if( commandToUndo->GetPickedItemLink(ii) == NULL ) - commandToUndo->SetPickedItemLink( CloneStruct( item ), ii ); + commandToUndo->SetPickedItemLink( DuplicateStruct( item, true ), ii ); wxASSERT( commandToUndo->GetPickedItemLink(ii) ); break; diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index b79f6a5f27..f76cdd8612 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -105,6 +105,9 @@ structures and cannot be undone.\nOk to continue renaming?" ); aSheet->ChangeFileName( this, fileName.GetFullPath() ); } } + + else + SaveCopyInUndoList( aSheet, UR_CHANGED ); aSheet->m_FileNameSize = ReturnValueFromString( g_UnitMetric, dlg.GetFileNameTextSize(), @@ -202,6 +205,7 @@ static void ExitSheet( WinEDA_DrawPanel* aPanel, wxDC* aDC ) screen->SetCurItem( NULL ); aPanel->ManageCurseur = NULL; aPanel->ForceCloseManageCurseur = NULL; + SAFE_DELETE( g_ItemToUndoCopy ); } @@ -213,6 +217,7 @@ static void ExitSheet( WinEDA_DrawPanel* aPanel, wxDC* aDC ) SCH_SHEET* WinEDA_SchematicFrame::CreateSheet( wxDC* aDC ) { g_ItemToRepeat = NULL; + SAFE_DELETE( g_ItemToUndoCopy ); SCH_SHEET* sheet = new SCH_SHEET( GetScreen()->m_Curseur ); @@ -273,6 +278,12 @@ void WinEDA_SchematicFrame::ReSizeSheet( SCH_SHEET* aSheet, wxDC* aDC ) DrawPanel->ManageCurseur = MoveOrResizeSheet; DrawPanel->ForceCloseManageCurseur = ExitSheet; DrawPanel->ManageCurseur( DrawPanel, aDC, true ); + + if( (aSheet->m_Flags & IS_NEW) == 0 ) // not already in edit, save a copy for undo/redo + { + delete g_ItemToUndoCopy; + g_ItemToUndoCopy = DuplicateStruct( aSheet, true ); + } } @@ -291,4 +302,10 @@ void WinEDA_SchematicFrame::StartMoveSheet( SCH_SHEET* aSheet, wxDC* aDC ) DrawPanel->ForceCloseManageCurseur = ExitSheet; DrawPanel->ManageCurseur( DrawPanel, aDC, true ); DrawPanel->CursorOn( aDC ); + + if( (aSheet->m_Flags & IS_NEW) == 0 ) // not already in edit, save a copy for undo/redo + { + delete g_ItemToUndoCopy; + g_ItemToUndoCopy = DuplicateStruct( aSheet, true ); + } } diff --git a/eeschema/sheetlab.cpp b/eeschema/sheetlab.cpp index 12632f8f11..8ffddfbcde 100644 --- a/eeschema/sheetlab.cpp +++ b/eeschema/sheetlab.cpp @@ -168,9 +168,14 @@ static void ExitPinSheet( WinEDA_DrawPanel* Panel, wxDC* DC ) void SCH_SHEET_PIN::Place( WinEDA_SchematicFrame* frame, wxDC* DC ) { SCH_SHEET* Sheet = (SCH_SHEET*) GetParent(); + SAFE_DELETE( g_ItemToUndoCopy ); + + int flags = m_Flags; + m_Flags = 0; - if( m_Flags & IS_NEW ) + if( flags & IS_NEW ) { + frame->SaveCopyInUndoList( Sheet, UR_CHANGED ); if( Sheet->m_Label == NULL ) Sheet->m_Label = this; else @@ -187,11 +192,20 @@ void SCH_SHEET_PIN::Place( WinEDA_SchematicFrame* frame, wxDC* DC ) } } } + + else // pin sheet was existing and only moved + { + wxPoint tmp = m_Pos; + m_Pos = s_InitialPosition; + m_Edge = 0; + if( m_Pos.x > ( Sheet->m_Pos.x + (Sheet->m_Size.x / 2) ) ) + m_Edge = 1; + frame->SaveCopyInUndoList( Sheet, UR_CHANGED ); + m_Pos = tmp; + } - m_Flags = 0; m_Pos.x = Sheet->m_Pos.x; m_Edge = 0; - if( frame->GetScreen()->m_Curseur.x > ( Sheet->m_Pos.x + (Sheet->m_Size.x / 2) ) ) { m_Edge = 1; @@ -350,11 +364,13 @@ SCH_SHEET_PIN* WinEDA_SchematicFrame::Import_PinSheet( SCH_SHEET* Sheet, if( (HLabel == NULL ) || SheetLabel ) { - DisplayError( this, _( "No new hierarchical labels found" ), 10 ); + DisplayInfoMessage( this, _( "No new hierarchical labels found" ), 10 ); return NULL; } OnModify( ); + SAFE_DELETE( g_ItemToUndoCopy ); + SaveCopyInUndoList( Sheet, UR_CHANGED ); NewSheetLabel = new SCH_SHEET_PIN( Sheet, wxPoint( 0, 0 ), HLabel->m_Text ); NewSheetLabel->m_Flags = IS_NEW;